Your compiler doesn't give you a warning when you write d = 0.01, because (1) when you use a feature it's expected that you already know how it works, and (2) it would have to give you an approximation warning (very nearly) every time you use a floating-point literal, which would be annoying to those who actually understand and need to use floating point arithmetic, not to mention that it would hide legitimate warnings.Uri Blass wrote:I get almost the sameZach Wegner wrote:Doubles can represent integers exactly, but that's not what we're doing. We're trying to represent fixed-point decimals of the form x.yy. You cannot represent 1/100 exactly in a double, as you must round at some point:Uri Blass wrote:I agree about point 1 but I disagree about 2.
You can represent every integer as double.
You even can have exactly the same evaluation when you replace integer by double and the only difference is that you are going to be slower.And though there is a one-to-one correspondence between every centipawn evaluation to its double representation, the rounding will crop up. Notice how 1/100 is rounded so that the double representation is bigger than 1/100? Try running this program:Code: Select all
0.0100000000000000002081668171172168513294309377670288085937500000000000000000000000000000000000000000
You would expect s to be either exactly 10, or maybe a bit bigger? Here's what it actually is:Code: Select all
#include <stdio.h> main(void){ double d = 0.01, s = 0; int i; for (i = 0; i < 1000; i++) s += d; printf("%.100f\n", s); }
Which is _less_ than 10.Code: Select all
9.9999999999998312461002569762058556079864501953125000000000000000000000000000000000000000000000000000
Now if you wanted to use "binary" values, and have your base unit be 1/256 or whatever of a pawn, go ahead. Or you could also use doubles with each number scaled up by 100 or so, but then what's the point?
I get
9.9999999999998312000000000000000000000000000000000000000000000000000000000000000000000000000000000000
I understand that 0.01 is binary approximation of 0.01 and it seems that the C is misleading.
I think that they simply should not allow me to write d=0.01 without warning by the compiler that d is not 0.01 but binary approximation of that value and double means
the finite set of non-zero values of the form s * m * 2e, where s is 1 or -1, and 0 < m < 253 and -1075 <= e <= 970.
.
I wonder why they do not do it.
I even could not see it based on clicking help on the word double and I had to search in google to find the following link that gives me the exact range of data
http://www.dotgnu.org/pnetlib-doc/System/Double.html
When I only click on help about double and later about data type range
I got simply that range of values of double is
1.7E +/- 308 (15 digits)
Clearly misleading.
Uri
However, it does appear that your documentation could have been a bit better. I'll have to admit though that I'm quite surprised that you didn't know floating-point values were binary approximations. I even thought it was implied in your response to Bob when I first read it.