inaccurate floats?

BlitzMax Forums/BlitzMax Programming/inaccurate floats?

NeuralizR(Posted 2005) [#1]
x:Float = 34
Print x
34.0000000

x:Float = 34.1
Print x
34.0999985

x:Float = 34.0999921
Print x
34.0999908


So umm, anybody care to explain this?

I've been looking around through the forums (searching and browsing) and maybe I'm missing it, but the only topics I can find related to this are about the problems with x:Float = (1310/100) for example not being equal to 13.1, which I can understand, no problem.

I'm sure there's some reason why when I say I want my float to be 34.0999921 it's returned as 34.0999908, I'd just like to actually understand it, not just know "that's the way it is". :)

Thanks,
Dave Mauldin (NeuralizR)


GrahamK(Posted 2005) [#2]
It's called internal representation and is common to all languages, it's just how it's represented. Most language apply some form of rounding to x digits, which resolves it.

If you do some searches on google for IEEE float representation, things should become clearer.


Floyd(Posted 2005) [#3]
There's some confusion about BlitzMax versus Blitz3D and BlitzPlus. They have different ways of displaying numbers. The actual numbers are the same, but Print shows different values.

In the case of x# = 34.1 the single precision representation is 4469555 / (2^17).
In decimal this is 34.09999847412109375, exactly.

Older versions of Blitz rounded the display to six digits, producing 34.1000, and then trimmed off the extra zeroes.

BlitzMax always rounds the display to nine digits, so 34.0999985 is displayed.

Note that x# is not exactly equal to 34.1, nor is it equal to any of the displayed values.


NeuralizR(Posted 2005) [#4]
From http://stevehollasch.com/cgindex/coding/ieeefloat.html :

"Floating-point representation - the most common solution - basically represents reals in scientific notation. Scientific notation represents numbers as a base number and an exponent. For example, 123.456 could be represented as 1.23456 × 102. In hexadecimal, the number 123.abc might be represented as 1.23abc × 162."

Best overall resource I found was:
http://en.wikipedia.org/wiki/Floating_point

Thanks for the tip Graham! :)

((( Floyd made his post while I was researching and writing up mine. Thanks for yours as well. :)))


ImaginaryHuman(Posted 2005) [#5]
It basically comes down to the idea that you use a floating point number to represent, digitally, a fractional amount of any precision. The problem is that there are only so many bits in which to represent the number and some numbers would need to be longer than others. So the numbers stored are more or less approximate - there isn't enough resolution in the storage of the number.

That's why you have the Double data type - so that it can represent bigger numbers and with more accuracy. I always figured it is totally normal to see slightly `off` values stored in the Float. Usually it doesn't matter, I guess it depends on your application. Drawing an object at 10.934828348 instead of 10.934828349 isn't a big deal.


Russell(Posted 2005) [#6]
Some languages, such as PowerBasic, have a variable type called "currency" which doesn't seem to have this problem, although it's a bit slower than floats I hear. Using currency variables, 34.1 does, indeed, equal 34.1.

For those that are interested, the currency type actually represents the defined float with binary coded decimal internally. It uses 10 bytes internally to do this...

Russell