MS Excel tries to be clever and disguise the most common places this is noticed. Give it =0.1+0.2-0.3 and it will see what you are trying to do and return 0. Give it anything slightly more complicated such as =(0.1+0.2-0.3) and this won't trip, in this example displaying 5.55112E-17 or similar.
Are you sure it is not showing the exact answer because the the the cell precision set to a single decimal digit?
0.30000000000000004
391–400 of 422 posts
Re: 0.30000000000000004
#392Earlier quoted context omitted.
> When people talk about non-determinism of floating point, what they usually mean is non-associativity, that is (x+y)+z may not be exactly equal to x+(y+z). Good example of this, in Python 3: >>> (0.1 + 0.2) + 0.3 0.6000000000000001 >>> 0.1 + (0.2 + 0.3) 0.6
Every single time you run those two statements, you’ll get the same result. Yes they're non-associative. But that's specified and documented. That's not the same thing as non-deterministic in any way.
Re: 0.30000000000000004
#393MS Excel tries to be clever and disguise the most common places this is noticed. Give it =0.1+0.2-0.3 and it will see what you are trying to do and return 0. Give it anything slightly more complicated such as =(0.1+0.2-0.3) and this won't trip, in this example displaying 5.55112E-17 or similar.
Are you sure it is not showing the exact answer because the the the cell precision set to a single decimal digit?
Re: 0.30000000000000004
#394Earlier quoted context omitted.
ES does have an arbitrarily large integer type, BigInt. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
It’s not supported everywhere though, so it’s not like you could use it to actually build a library, you would need to use something that fell back to Doubles anyway.
IIRC some JS engines are capable of detecting many circumstances where floating-point is not needed, particularly for simple cases like loop counters, and their JiT compilers will produce code that uses integer values instead of floats for those purposes - but how reliable that is for cases any more complex than that I don't know.
Re: 0.30000000000000004
#395The big issue here is what you're going to use your numbers for. If you're going to do a lot of fast floating point operations for something like graphics or neural networks, these errors are fine. Speed is more important than exact accuracy. If you're handling money, or numbers representing some other real, important concern where accuracy matters, most likely any number you intend to show to the user as a number, f…
Hear, hear! It would be great if javascript had any integral type that we could build decimals, rationals, arbitrarily-large integers and so on off. It’s technically doable with doubles if you really know what you’re doing, but it would be so much easier with an integral type.
Re: 0.30000000000000004
#396Earlier quoted context omitted.
Fixed/floating is an interesting tradeoff for many real-time strategy games too where changes in game state are a synchronized simulation. Fixed point math in software can give more reliable and cross-platform math operations, but with a performance cost (eg: Homeworld: Deserts of Kharak). Using the CPU's floating-point hardware is faster, but you often have to ensure the correct CPU registers are set before doing ca…
I currently build deterministic multiplayer WebGL games in Unity, built via C#->IL2CPP->Emscripten->WASM. The server is the same code base running on Microsoft's .Net runtime. The chances of being able to run deterministic floating point calculations across this stack is basically zero (even leaving aside that the games are often run on ARM chips), and so we use this library when floats are absolutely necessary (but…
Our game would snapshot the entire game state every few seconds and send that back to server to detect desyncs and cheaters. Floating point math, to our astonishment, was not the source of any non-determinism.
I'm 80% sure that only source of non-determinism we encountered were from trig functions, so we just hard-coded lookup tables.
1: https://guardiansofatlas.com/
2: It was 2012 when we started.
Re: 0.30000000000000004
#397Earlier quoted context omitted.
My day job is high performance financial model implementation. Floats storing dollar amounts are the norm for predictions. Operating on values that are linear combinations of integer fractions multiplied by irrational constants (such as Euler’s number) is perfectly possible, but it’s much more performant to be aware of floating point epsilon when writing modeling code.
Financial models are predictive, they don't have to be accurate to a penny, right? Unlike processing actual money people own. (I do some work with predictive simulations about money, but outside finance, and there we care that the result has accurate order of magnitude. Floats were used extensively in the project; I actually upgraded them to doubles for the sake of handling larger order of magnitude spans.)
Re: 0.30000000000000004
#398Earlier quoted context omitted.
Right, it is not correct. But many programs do it wrong. If you just do a couple of additions the problem will never be noticed. It's easy to write a program that sums up 0.01 until the result is not equal to n * 0.01. Not at my computer now, so I can't do it again. I remember n was bigger to be relevant for any supermarket cashier. But of course applications exist where it matters.
But it is correct. > It's easy to write a program that sums up 0.01 until the result is not equal to n * 0.01. It's not easy to do that if you use a floating point decimal type, like I recommended . For instance, using C#'s decimal, that will take you somewhere in the neighborhood of 10 to the 26 iterations. With a binary floating point number, it's less than 10.
Many languages have no decimal support built in or at least it is not the default type. With a binary type the rounding becomes already visible after 10959 additions of 1 cent.
#include
#include
#include
bool compare(int cents, float sum) {
char buf[20], floatbuf[24];
int len;
bool result;
len = sprintf(buf, "%d", cents / 100 ) ;
sprintf(buf + len , ".%02d" , cents % 100 ) ;
sprintf(floatbuf, "%0.2f", sum) ;
result = ! strcmp(buf, floatbuf) ;
if (! result)
printf( "Cents: %d, exact: %s, calculated %s\n", cents, buf, floatbuf) ;
return result;
}
int main() {
float cent = 0.01f, sum = 0.0f;
for (int i=0 ; compare(i, sum) ; i++) {
sum += cent;
}
return 0;
}
Result: Cents: 10959, exact: 109.59, calculated 109.60
This is on my 64 bit Intel, Linux, gcc, glibc. But I guess most machines use IEEE floating point these days so it should not vary a lot.Re: 0.30000000000000004
#399Earlier quoted context omitted.
> Storing money in floating point is fine. Just round to the nearest atomic unit when displaying. Well, it's not just a display issue. In accounting, associativity and commutativity are important. People do care that `a + b + c - a == c + b` should evaluate to “true”.
It appears you did not see the critical point in the above comment. "Performing arithmetic operations against money in floating point is the dangerous part, as error can accumulate beyond an atomic unit."
Re: 0.30000000000000004
#400When did RFC1035 get thrown under the bus? According to it, with respect to domain name labels, "They must start with a letter" (2.3.1).
https://tools.ietf.org/html/rfc1123#page-13
One aspect of host name syntax is hereby changed: the restriction on the first character is relaxed to allow either a letter or a digit. Host software MUST support this more liberal syntax.