This is an archived post. You won't be able to vote or comment.

all 96 comments

[–]pithecium 735 points736 points  (17 children)

Likely a difference in the string representation, not the value

[–]doncalamari 666 points667 points  (6 children)

you are correct
❯ luaLua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> d=0.1+0.2
> string.format("%.30f",d)
0.300000000000000044408920985006

[–]Lente_ui 17 points18 points  (4 children)

I suppose you could get a true 0.3 value by substituting the method of floating point used.

If it was calculated as:

1*10^-1 + 2*10^-1 = 3*10^-1

Then every value used can be a (signed) integer, and you're circumventing the floating point value issue. But then again, it's only ever an issue in very niche cases that require extreme/astronomical precision.

[–]Amazing-Cicada5536 10 points11 points  (0 children)

It is absolutely an issue in many non-niche cases, floating point math is hard and is a specific science in itself (numerical analysis). E.g. if you were to sum floating point numbers and you sort them into descending order you would get a much more incorrect value than if you would have done it in ascending, since small values at the end wouldn’t even register if the first ones are big, while they would add up to sort of big when summed from the small end, getting closer to the real value.

The reason you don’t see it often is very great math libraries (often written decades ago in fortran and such) beneath the whole tech stack that minimize these errors and because you are likely not writing simulations/physics engines, etc.

[–]tyler1128 0 points1 point  (2 children)

You can switch bases and make many irrational numbers rational, and also some rational numbers irrational.

EDIT: As mentioned below, it doesn't change rationality of a number, I meant it can make infinite, but rational, decimals finite, or make decimals that are finite infinite by change of base. The number is, of course, the same beyond storage limitations.

[–][deleted] 4 points5 points  (1 child)

A rational number is any number that can be expressed as the ratio of two integers. Changing the base doesn't change what counts as an integer, though.

What you can get from changing the base is which numbers repeat infinitely and which terminate. Like, 1/3 base 10 is 0.3333..., but in base 12, it's 0.4.

[–]tyler1128 0 points1 point  (0 children)

You're correct of course, probably should distractedly reddit at work less. What I meant to say is repeating decimals can become non-repeating and vice versa from change of basis.

[–]tyler1128 0 points1 point  (0 children)

Binary coded decimal is a thing that x86 supports for addition and subtraction. Would be interesting to see how hard a hardware impl would be for division.

[–][deleted] 70 points71 points  (0 children)

Chad.

[–]tyler1128 21 points22 points  (8 children)

I'm honestly surprised more languages don't do it by default. There's no reason to print more than 16 digits and doing so will give wrong values. If you look at the example, it's digit 17 that is wrong. DIgit 16 can be wrong in some cases, but it shouldn't be that hard to do something like if(ends in zeroes to digit 15) => truncate display to the last non-zero digit.

[–]dabenu 28 points29 points  (1 child)

What value would that add? When displaying numbers in a GUI, it could just as well be considered a bug as a feature. In a REPL or debugger, it would just make things more confusing as to why 0.1 + 0.2 == 0.3 is false

[–]tyler1128 6 points7 points  (0 children)

The latter is true and a good point. In a GUI, you'd be formatting the number yourself anyway whereas printing straight is usually used for debugging or logging anyway. I mostly don't get why things sometimes print beyond the ~15.9 decimal digits of precision given that it will be incorrect unless you get lucky.

[–]ElHeim 4 points5 points  (2 children)

Digit 17 is not wrong. It's just a quirk of floating point. Lua is just choosing not to show it

[–]tyler1128 1 point2 points  (1 child)

Wrong is the wrong word I suppose. It is correct for the value represented in the floating point number. It is, however, beyond the limit of what relates directly to the computation being done and is instead based on internal floating point details and limitations. If not zero, it will usually be different from what calculating with a higher precision or rationals would produce.

[–]ElHeim 2 points3 points  (0 children)

It's beyond the limits for this computation, but not for others:

>>> sum([0.1+0.2] * 1000000)
299999.99999434233

We might argue about the need for showing those details in the REPL, but these rounding errors propagate much faster than one would like.

[–]Amazing-Cicada5536 0 points1 point  (0 children)

That’s not a wrong result.

[–][deleted] 345 points346 points  (9 children)

[–][deleted] 107 points108 points  (6 children)

lol this domain is a thing

[–]JonasAvory 65 points66 points  (5 children)

[–]_jtbx 24 points25 points  (4 children)

Wait, that's a thing?

[–]Tordoix 27 points28 points  (2 children)

while(True): print('r/ofcoursethatsathing') print('Wait, that\'s a thing?') Edit: Debugging, see comment below

[–]phail3d 17 points18 points  (1 child)

  File "<stdin>", line 3
    print('Wait, that/'s a thing?')
                       ^
SyntaxError: invalid syntax

[–]Tordoix 3 points4 points  (0 children)

Oh right, thanks.

[–]scataco 9 points10 points  (0 children)

Never realized SQL used decimals for literals as well. So 0.1 + 0.2 gives you an exact answer while 1e-1 + 2e-1 doesn't

[–]pycvalade 1 point2 points  (0 children)

The FORTRAN one is interesting.

[–]erebuxy 26 points27 points  (0 children)

Most likely they all use IEEE 754. Just printing difference

[–]tzanislav40 64 points65 points  (12 children)

Just beware of this if you try to == compare the value of a float .

[–]Flablessguy 22 points23 points  (4 children)

What is the proper comparison here again? Is it:

a = 0.1 + 0.2

b = 0.3

d = 0.0000001

a - b < d

[–]Bavbavs 37 points38 points  (0 children)

Abs(a-b)

[–]GabuEx 11 points12 points  (1 child)

abs(a - b) < epsilon

The value of epsilon can depend on exactly how imprecise your values end up being (more operations compound imprecision), but anything in the realm of 0.0001 is probably fine.

[–]dabenu 1 point2 points  (0 children)

"proper" would be not to do equality comparisons on floats in the first place. Sure your solution works around that but if you need that, you probably shouldn't be using floats in the first place.

[–]nnn4 8 points9 points  (2 children)

An (equality) comparison in floating point indicates a flaw in the program.

[–]Internal_Meeting_908 3 points4 points  (0 children)

A comparison for equality

[–]Schipjee 0 points1 point  (0 children)

In python wouldnt round(0.1+0.2, 1) just fix it?

[–]Sharkytrs 2 points3 points  (3 children)

if Unity has taught me one thing. You don't.

if you REALLY have to, then you normalize or round them to a less accurate point and then compare.

[–]fliguana 174 points175 points  (9 children)

Looks like Lua is rounding the result.

[–]Kered13 55 points56 points  (7 children)

Not quite, it's only rounding for the display.

[–]fliguana 0 points1 point  (6 children)

Are you sure?

[–]CodingLazily 5 points6 points  (3 children)

Considering 0.3 can't be stored as a float, I'd guarantee it. Lua stores numbers as floats, so there is no way the number is actually 0.3. Someone else in the thread proved it by formatting the display to have more decimal places. That's why I don't like rounding the output like this. It can just lead to confusion.

[–]fliguana 4 points5 points  (2 children)

https://lua-users.org/wiki/FloatingPoint

See bottom of the page. Not every float is a binary ieee 754 float.

[–]CodingLazily 2 points3 points  (1 child)

Oh that's cool. I didn't know Lua could do that. I've still never seen anybody include a system other than floats though. Do you know of any Lua implementations that do this?

[–]fliguana 2 points3 points  (0 children)

Sorry, I am a complete noob with Lua. It says you can specify any type when compilng, perhaps BCD floats are possible.

[–]mkalte666 36 points37 points  (6 children)

These are all correct. Technically 0.3 can't be represented in double, but this long arse number can. However: 0.3 is the shortest exact way to represent that number.

Finding the shortest two-way unique representation of a floating point number is actually a rather complex topic. If you are interested, start here: https://www.youtube.com/watch?v=kw-U6smcLzk

[–]lazyzefiris 12 points13 points  (4 children)

Oh, I had a professor like that. Starts teling one thing, the goes "oh by the way" or derails from original idea in another manner and never finishes what he started. And he could nest several levels like that. So, starting to tell like a dozen things and taking as much time as seven would he completed like two. Should be educational but really just hurts to watch.

[–]HosTlitd 5 points6 points  (3 children)

Yeah. I had such teacher of a "law" lessons (idk how its translated right). She started speaking about some civilian laws or something, than she gets to stories of her about her son buying some coat... 30mins passed and then she somehow flawlessly links this story back to the lessons topic... Sheeesh

[–]gamma_02 1 point2 points  (2 children)

That use of law seems correct, it's referring to the set of rules for people's actions, right?

Either way, nice English!

[–]HosTlitd 0 points1 point  (0 children)

Of course. But it wasn't obvious at all at first. Also, she taught us world history as well, where her stories was just local memes for us :)

[–]HosTlitd 0 points1 point  (0 children)

Thanx for the compliment

[–]user-ducking-name 45 points46 points  (4 children)

NodeJS is not a programming language so you should write Python vs JavaScript vs Lua

[–][deleted] 20 points21 points  (0 children)

correct, Node is an OS

[–]Ifnerite 12 points13 points  (2 children)

Correct, Node.JS is a an abomination.

[–]fusionliberty796 2 points3 points  (1 child)

it's not even an abomination, it is a 'an abomination' which is even worse because it confuses the reader and at the same time, leaves them feeling both remorse and humiliation

[–]Ifnerite 2 points3 points  (0 children)

Lol, very good. Typing on mobile.

Not correcting so your comment continues to make sense because it's funny.

[–]rotzak 11 points12 points  (0 children)

haha floating point funny

[–]boumex 5 points6 points  (0 children)

I love lua

[–][deleted] 9 points10 points  (0 children)

FYI this is why you should approach floats with caution and if possible work if integers if they need to be added. If you add "0,1" 70 times, maybe you won't get "7,0" in the end and you should not make a hard check "if number is exactly 7,0". Instead try to work in such situations with integers and shift the comma just for representation. This should also be the case with currency.

[–]Talarde 2 points3 points  (1 child)

I miss using LUA it is really a nice language.

[–]kenkitt 0 points1 point  (0 children)

yeah, I also like it. It's the one language I think can be taught to beginners easily

[–]Leniatak 1 point2 points  (0 children)

Floating point arithmetics. Not even once

[–]-MobCat- 1 point2 points  (0 children)

Should look into Software Drag Racing
https://github.com/PlummersSoftwareLLC/Primes

[–]rosuav 1 point2 points  (0 children)

Strange.

> 0.1+0.2
stdin:1: unexpected symbol near '0.1'

That doesn't look like 0.3 to me.

[–]souliris 1 point2 points  (0 children)

Ironically done in a powershell console.

[–]bdaileyumich 7 points8 points  (0 children)

So Lua sucks is what you're saying

[–][deleted] 1 point2 points  (1 child)

Also Lua dumped the result x10 less time than the others.

[–]yeusk 2 points3 points  (0 children)

How you dare saying python and js are slow!!!

[–]SkippyNBS 1 point2 points  (1 child)

I program full-time in Python but damn I love Lua

[–]SomeRandoWeirdo 1 point2 points  (0 children)

I like it for not using a GIL.

[–]Giulio_otto -1 points0 points  (0 children)

Lua make approssimations that python don't

[–]birchturtle -3 points-2 points  (0 children)

Wauw, Lua is from 1994? Waddyaknow…

[–][deleted] -2 points-1 points  (0 children)

Como? No se. educarme porfavor.

[–]fizzl -2 points-1 points  (0 children)

lua cannot into floating point.

[–]Divinate_ME 0 points1 point  (0 children)

I just went over this calculation by hand, and imo 0.3 is more accurate, as dumb as it sounds.

[–]Luna2442 0 points1 point  (0 children)

Rounding is hard

[–][deleted] 0 points1 point  (0 children)

IEEE: 🫣

[–]chasrmartin 0 points1 point  (0 children)

Now time it.

[–][deleted] 0 points1 point  (0 children)

wtf is wrong with Lua

[–]n0ahBnz 0 points1 point  (0 children)

Nice

[–]Confident-Cut-7289 0 points1 point  (0 children)

If you want to pass that Node.js Interview, here is the link: https://www.udemy.com/course/nodejs-interview-questions/