1. The Joy of
Programming
How ‘C’mart Are You? S.G. GANESH
A peek into those curious numbers that float in the air.
T
he discussion assumes that the underlying platform with double precision.
supports the IEEE 754 standard for floating point Note that the binary representation of floating point
arithmetic. Determine the output of the following numbers (also in the IEEE 754 standard) has limitations in
two programs: the range of values it can represent and the accuracy of
the representation. Practical implication of this is that the
// Program I simple arithmetic calculations and comparisons can fail; for
#include <assert.h> example, 0.9 + 0.5 need not be equal to 1.4, nor
GUEST COLUMN
0.900001—0.9 needs to be equal to 0.000001;
int main() { because of that, related calculations can have
float f = 0.0; gross errors (for example, floor(3.1—0.1) is not
int i; 3). For the same reason, the cumulative effect of
for(i = 0; i < 1000; i++) the arithmetic operations can be wrong.
f += 0.001; So, direct comparisons of the floating point
assert(f == 1.000); numbers should not be done and assumptions
} should not be made on the accuracy of the values,
as is done in the usual (decimal) mathematics.
// Program II This fact is illustrated by the first program in
#include <stdio.h> which, if you add 0.001 a thousand times, it’s not
equal to 1.0 (but is little less than that—
int main() { 0.999991); hence, the assertion failure!
printf(“loop starts now...n”); Now let’s move on to the second program.
for(float f = 0.0; f < 20000000.0; f++) Since floating point arithmetic is not accurate, the
; // just loop over, do nothing operations can result in loss of precision and
printf(“...done!”); rounding errors. In the loop, when the value of f
} reaches 16777216.0, adding 1 doesn’t increment
the value of f by 1, but gets rounded off. You can
“Ah, easy...” you say! But let’s see the answers first. verify it with the following code segment:
Program I fails with the assertion failure and Program II
gets into an infinite loop after printing: float f = 16777216.0;
assert(f == (f + 1));
“loop starts now...n”.
This doesn’t fail with an assertion failure and works
Before seeing the explanation, let’s have a quick fine! Now you know why it’s a bad idea to use floating point
tutorial on floating point numbers. numbers in loops!
The types that can represent the numbers with decimal
points (where the position of the decimal point is not
fixed, or in other words, is floating) are known as floating S.G. Ganesh is an engineer in Hewlett-Packard’s C++
point numbers. There is a standard available for specifying compiler team. He has authored a book “Deep C” (ISBN 81-
7656-501-6). He is also a member of the ANSI/ISO C++
the implementation of floating point numbers (The IEEE
Standardisation committee (JTC1/SC22/WG21)
754 Floating Point Standard). Based on that, typically, C
representing HP. You can reach him at
compilers support float for representing single precision sgganesh@gmail.com.
numbers and double type for representing the numbers
www.linuxforu.com | LINUX FOR YOU | FEBRUARY 2007 119
CMYK