Calculate which numbers cause problems when conver

2019-06-11 13:56发布

问题:

I know when converting some numbers from binary to floating point there can be problems.

For example: 1.4 results in 1.39999. 6.2 is 6.1999999, 6.6 is 6.599999, etc.

Is there a way to calculate which numbers will cause these problems? Like create some sort of spreadsheet or database with numbers from 1-50,000 which don't convert exactly?

回答1:

The errors in floating point calculations are rooted in the way that floating point numbers are stored. Depending on which precision you are using (usually either single (float) or double-precision). Double-precision floats take more space, but are roughly twice as precise.

Floating point numbers are typically stored in an IEEE format and thus only the most significant bits are included.

In a string of bits stored in this way to represent a floating point number, there are different parts that comprise the number. First, there is a sign bit indicating whether the number is positive or negative. Next, the exponent portion of the number is stored (in single-precision floats, this takes 8 bits). After the exponent, all remaining bits represent the significant digits of the number. Thus, the bits 1 10000000 01000000000000000000000 represent -0.5 The sign bit (first one) signifies that the number is negative. The next eight bits are the exponent. Usually, the exponent is stored with a bias so that small numbers may be stored precisely in addition to large ones. To do this, the exponent used for calculations is -127 (if an 8 bit exponent) + the exponent bits interpreted as an integer (in our case 128). All remaining bits signify the significant digits of the number starting with the ones place and moving rightward from there we cut the value in half each time (1 is 1, but 01 is 1/2 and 001 is 1/4) in our case the total number is -0.5 (-1 for the sign bit * 2^1 for the exponent * 0.5 for the remaining bits)

For further example, here is a converter that uses checkboxes to indicate the bits. At worst, you could write a bot to test all of the combinations you care about.

In general, if it cannot be described with a fraction that is not directly made of combinations of powers of two, it will be rounded. (If you can't get it with 1/2 + 1/4 + 1/8 etc. it will probably be rounded)



回答2:

Almost all numbers are troublesome. The minor exception are those, that when repeatedly multiplied by 2 get rid of the fractional part and end up being less than 2^24.

e.g.

0.125 -> 0.25 -> 0.5 -> 1.0 !  OK
6.4 --> 12.8 --> 25.6 -> 51.2 -> 102.4 : we got a cycle! (.4 .8 .6 .2 ... )

EDIT

Given the purpose/context of the issue, the inexactness seems to cause trouble when the floating point is rounded towards zero.

e.g.

10.2 == 10.199999809, when the next floating point would be  
next == 10.200000763  <-- the difference to the wanted value is ~4 times higher
vs.
10.3 == 10.300000197, when the previous (rounded down fp would be)
prev == 10.299992370, <-- this would have been also ~4x further from away

Perhaps it's time to talk to the programmer of the CNC driver...