Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Dec 17, 2012, 11:23 AM   #1
VulchR
macrumors 68000
 
VulchR's Avatar
 
Join Date: Jun 2009
Location: Scotland
Very odd error in looping - possible bug in AWK maths library?

I use AWK (C-like programming language used to parse tables - and, yes, I know that's primitive of me). Check out the following behaviour

for (x=0.01;x<=0.05;x+=0.01) Stops at 0.05 as expected
for (x=0.01;x<=0.06;x+=0.01) Stops at 0.05
for (x=0.01;x<=0.06000001;x+=0.01) Stops at 0.06 as expected
for (x=0.1;x<=0.6;x+=0.1) Stops at 0.6, as expected
for (x=0.01;x<=0.10;x+=0.01) Stops at 0.10 as expected and steps through 0.06 just fine

Possible maths library bug? Anybody else able to confirm this perhaps with C (I am not sure, but I presume AWK uses C's maths libraries)?

Mac OS X 10.8.2
iMac 27" i7
__________________
My first was a Mac+. Now I own an iPhone with 3.5x the pixels, a colour display, WiFi, 512x the RAM, >1500x the data storage, and 100x the speed. And it fits in the palm of my hand.

Last edited by VulchR; Dec 17, 2012 at 11:39 AM.
VulchR is offline   0 Reply With Quote
Old Dec 17, 2012, 11:48 AM   #2
boffo
macrumors newbie
 
Join Date: Oct 2006
Location: Lambeth
Comparing floating point numbers for equality can lead to unexpected results as you have encountered here. This is because some numbers which can be precisely represented as decimals can't be represented as floating point numbers.

Reimplementing your program in C and printing the values of x with a large degree of precision gives me this:

Code:
  double x;
  for (x = 0.01; x <= 0.06; x += 0.01)
    printf("%4.20f\n", x);
which prints out

Code:
0.01000000000000000000
0.02000000000000000000
0.02999999999999999900
0.04000000000000000100
0.05000000000000000300
You can see that the next value would be greater than 0.06, and so the x <= 0.06 test would fail.

Instead of your second example:

Code:
for (x=0.01;x<=0.06;x+=0.01)
you are better off doing something like

Code:
for (x = 1; x <= 6; x += 1)
  actual_x = x / 100.0
I'm not familiar enough with awk to try this for you but something along these lines should work.

The standard reference on this kind of thing is

What Every Computer Scientist Should Know About Floating-Point Arithmetic.
boffo is offline   0 Reply With Quote
Old Dec 17, 2012, 11:58 AM   #3
Mac_Max
macrumors 6502
 
Join Date: Mar 2004
This doesn't surprise me too much and I don't think it's an actual bug. Representing decimal fractions in binary is difficult. .5 is easy because it takes only one bit of precision after the decimal point. .06 requires much more.

If you must compare fractional values I'd suggest making sure you're using the highest precision floating point type in AWK, using a larger comparison number, and using only < rather than <=. 2^-4 is -0.0625 so that wouldn't be a bad value to try depending on the precision you need and have available.

Another trick if you're reading strings and converting them to numbers is to pad the numbers with enough zeros that everything becomes an integer. Precision issues mostly go out the window at that point.
Mac_Max is offline   0 Reply With Quote
Old Dec 17, 2012, 03:23 PM   #4
ytk
macrumors regular
 
Join Date: Jul 2010
This is how floating point numbers work. You can verify this by running either python or irb from the command line and typing in
Code:
(0.05 + 0.01) <= 0.06
Both Python and Ruby will return false. Additionally, Python by default doesn't round off floating point numbers, so you'll find that 0.05 + 0.01 actually returns 0.060000000000000005.

The best way to do this would be as boffo pointed out: Keep things in the integer world for comparison purposes, then only convert to floating point when actually needed for performing a calculation.
ytk is offline   0 Reply With Quote
Old Dec 18, 2012, 04:51 AM   #5
VulchR
Thread Starter
macrumors 68000
 
VulchR's Avatar
 
Join Date: Jun 2009
Location: Scotland
Quote:
Originally Posted by boffo View Post
C...
you are better off doing something like

Code:
for (x = 1; x <= 6; x += 1)
  actual_x = x / 100.0
I'm not familiar enough with awk to try this for you but something along these lines should work.

The standard reference on this kind of thing is

What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Quote:
Originally Posted by Mac_Max View Post
This doesn't surprise me too much and I don't think it's an actual bug. ...

If you must compare fractional values I'd suggest making sure you're using the highest precision floating point type in AWK, using a larger comparison number, and using only < rather than <=. 2^-4 is -0.0625 so that wouldn't be a bad value to try depending on the precision you need and have available.
Quote:
Originally Posted by ytk View Post
This is how floating point numbers work...
Thanks to all of you for your helpful replies. I think my error was to assume that the floating point representation used an exponent in base 10 (after reading it seems that the IEEE standard is base 2, which of course makes more sense). That's why the loop doesn't work with 0.06 but does with 0.6. Sigh ... been computing for 30 years, but feel like a noob...
__________________
My first was a Mac+. Now I own an iPhone with 3.5x the pixels, a colour display, WiFi, 512x the RAM, >1500x the data storage, and 100x the speed. And it fits in the palm of my hand.
VulchR is offline   1 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Tags
awk, bug, looping

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Odd Safari bug when printing to PDF chriscl OS X Mavericks (10.9) 2 Oct 12, 2013 01:21 PM
Odd iMessage Bug Truncates Last Word of Certain Text Phrases MacRumors MacRumors.com News Discussion 105 Sep 16, 2013 08:48 PM
Odd Finder bug Soundflunky OS X Mavericks (10.9) 4 Aug 11, 2013 10:23 PM
Odd Mountain Lion Crashing Bug Brings Down Nearly Any App MacRumors MacRumors.com News Discussion 188 Apr 15, 2013 02:50 AM

Forum Jump

All times are GMT -5. The time now is 12:16 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC