From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 27 Nov 91 16:19:55 GMT From: CNAM.CNAM.FR!bortz@ucbvax.Berkeley.EDU Subject: Re: Numeric problem with Ada Message-ID: <9111271619.AA13105@cnam.cnam.fr> List-Id: Thanks to all for the replies to my question about why C and Ada give two different results in "equivalent" numeric programs. Two kinds of solution were presented: those who said it was a problem in the I/O library and those who were looking toward the use of double-precision arithmetic by the C compiler. From the following modification of my test program (to suppress problems related with I/O), I think the second hypothesis is the good one. Here is the new program: Ada: if Z2 /= 18.0 then TEXT_IO.PUT_LINE ("Z2 /= 18.0"); else TEXT_IO.PUT_LINE ("Z2 = 18.0"); end if; C: if (z2 != 18.0) printf ("z2 != 18.0\n"); else printf ("z2 = 18.0\n"); Ada finds that Z2 /= 18.0 and C that z2 = 18.0. So the difference is really in internal computations. Two replies by E-mail were specially interesting: pragma BEGIN_QUOTATION (hilfingr@tully.cs.berkeley.edu "Paul N. Hilfinger"); C implementations generally DO use double precision (the new ISO stanard calls for it in this case; both of the constants 2.6 and 0.2 are double-precision, lacking any suffix to the contrary). When I tried this on a Sun 3, the compiler generated double-precision instructions and got the result you indicated (18.000000). When I changed the calculation of z2 to read z2 = (float) 2.6 * mz - (float) 0.2; the result was printed as 17.999999 (I used gcc version 1.39 on a Sun3). Perhaps you misread the assembly language code (those mnemonics ARE rather cryptic). pragma END_QUOTATION (hilfingr@tully.cs.berkeley.edu "Paul N. Hilfinger"); I agree with the possibility that I missed something in the assembly code (I prefer to read Ada!). pragma BEGIN_QUOTATION (Per-Gunnar.Johansson@imsa.hv.se "Per-Gunnar Johansson") ; The computer store Your object in a binary representation, and if You have six digits in the decimal system You have about 20 digits in the binary system. If You wamt to store a float-object the coputer transform it on the form number = m * (2 ** e), where 0.5 <= m < 1 or m = 0. It is no problem with the number 7 (7 = 0.875 * (2 ** 3), because 0.875 in the decimal system is exact 0.111 in the binary system. BUT, the number 2.6 = 0.65 * (2 ** 2), and 0.65 in the decimal system is 0.1010 0110 0110 0110 0110 ..... (and so on), in the binary system. The representation in Your computer, with six decimal digits, is about 20 binary digits. It means that Your computer represent the number 2.6 with m = 0.1010 0110 0110 0110 in the binary systemand it is about 0.649999619 in the decimal system, so (2.6 =) 0.649999619 * (2 ** 2) = 2.599998476. In the same way (0.2 =) 0.199999809 In that way, You calculating operation 2.6 * 7 - 0.2 = = 20599998476 * 7 - 0.199999809 = = 17.99998952 It is not 17.999998 but I think it maybe depend on the accurancy on my pocket calculator. pragma END_QUOTATION (Per-Gunnar.Johansson@imsa.hv.se "Per-Gunnar Johansson"); Stephane Bortzmeyer Conservatoire National des Arts et Metiers bortzmeyer@vcnam.cnam.fr Laboratoire d'Informatique bortz@cnam.cnam.fr 292, rue Saint-Martin 75141 Paris Cedex 03 France "C'est la nuit qu'il est beau de croire a la lumiere." E. Rostand