Path: utzoo!censor!geac!torsqnt!tmsoft!list-injector Newsgroups: can.usrgroup Subject: C code Message-ID: <9003010101.AA08961@redvax> Date: 1 Mar 90 01:01:35 GMT Reply-To: redvax!hugh (D. Hugh Redelmeier) Distribution: ont Lines: 60 | From: Steve Bird | | Here's another interesting piece. | | /* floaterr.c--demonstrates round-off error */ | # include | main() | { | float a,b; | b = 2.0e20 + 1.0; | a = b - 2.0e20; | printf("%f \n",a); | } | | When compiled the program returns the number 4008175468544.000000 . | Now when the program is modified to read : | | /* floaterr.c--demonstrates round-off error */ | # include | main() | { | float a,b; | b = 2.0e20 + 1.0; | a = 2.0e20; | printf("%f \n",b - a); | } | | The program returns 0.000000 . Why ? In one case, you are evaluating ((double) (float) 2.0e20) - 2.0e20 In the other case, you are evaluating ((double) (float) 2.0e20) - ((double) (float) 2.0e20) The former represents the roundoff in representing 2.0e20 in single precision. The latter ought to be zero. Here is a simpler version of your programs. Note that the "+ 1.0" has no effect. /* floaterr.c--demonstrates round-off error */ # include int main() { printf("%f\n",((double) (float) 2.0e20) - 2.0e20); /*4008175468544.000000*/ printf("%f\n", ((double) (float) 2.0e20) - ((double) (float) 2.0e20)); /*0.000000*/ return 0; } For questions like this, it is useful to know the compiler and machine. It appears to use IEEE f.p. so I was able the reproduce it using RedC on my Sun 3. Hugh Redelmeier {utcsri, yunexus, uunet!attcan, utzoo, hcr}!redvax!hugh When all else fails: hugh@csri.toronto.edu +1 416 482-8253