5 minute example of floating point making funky geometry

Imagine you want to measure the width of an object. How do you do this?

Lets say you have no ruler. You only know the distance of the object’s corners from an origin point. Say the far edge is 1.016 mm and the near edge is 1.000 mm.

Well, you might say, you can subtract one coordinate from the other. 1.016 mm minus 1.000 mm is 0.016 mm. The width of the object is 0.016mm. That might seem small, but … in fact, there are 3d printers that can print at that resolution.

But what is the width of that object if you, say, moved it 1000 mm in space? Well, you might think the width is the same! But…. if you are working in floating point coordinates… you would be wrong! The width of the object changes as the object moves through space… because the resolution of floating point numbers is higher near the origin point than it is farther away.

As you can see from the code below…. in a floating point world, the width of the object at 1000mm is going to be 0.015999999. This doesn’t seem like alot…. until you think about trying to write code to measure whether one object is wider or narrower than another object. In the computers mind, 0.01599999 is not the same thing as 0.01600000. You might say “well i can put a fudge factor in there”… can you? How much? Will it be different for different distances from the origin point? Yes, there are ways to answer this question….

…. but it ain’t simple.

Here is the example code,, in Python language, it takes an object with a near side at 1.0 mm and far side at 1+0.016mm from origin. Then it calculates the width by subtracting the coordinates. Then it moves the object farther out in space, printing the results of the calculation at each step.

while x<1000000:
        lo,hi,width = x,x+0.016,hi-lo
        hix = x+0.016
        widthx = hix-lox
        print "lo x %.30f" % lox
        print "hix %.30f" % hix
        print 'widthx %.30f' % widthqx
        x *= 10 

Results of running:

lox 1.000000000000000000000000000000
hix 1.016000000000000014210854715202
widthx 0.016000000000000014210854715202

lox 10.000000000000000000000000000000
hix 10.016000000000000014210854715202
widthx 0.016000000000000014210854715202

lox 100.000000000000000000000000000000
hix 100.016000000000005343281372915953
widthx 0.016000000000005343281372915953

lox 1000.000000000000000000000000000000
hix 1000.015999999999962710717227309942
widthx 0.015999999999962710717227309942

lox 10000.000000000000000000000000000000
hix 10000.015999999999621650204062461853
widthx 0.015999999999621650204062461853

lox 100000.000000000000000000000000000000
hix 100000.016000000003259629011154174805
widthx 0.016000000003259629011154174805

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s