result of double*double is no double 
Author Message
 result of double*double is no double

In the following code there is a difference in the output of m and n
where I think shouldn't be one. The program prints (on Borland C DOS 3.1,
IBM C-Set++ OS/2 and gcc 2.5.8 OS/2) the following:

1.332 1.333

The problem here is apparently that the result of 1000*m is not a double
internally. In the first case 1000*m is directly converted to
a long whereas in the second case 1000*n is first stored in double n
before being converted to a long.

I tried to switch off 'fast floating point' options on all compilers, but
it didn't help. My question here is: Is this result conforming to the
ANSI standard (I don't have it here)?

When I changed n,m to be long double in Borland both results became
identical (1.332). This leads me to the conclusion that the calculation
of 1000*m is performed with long doubles (probably using the FPU).

Another point: When compiling with gcc with option -O2 the program
prints 1.333 1.333.

#include <stdio.h>

int main(void)
{
  double m,n;

  n=m=1.333;

  m=(long)(1000*m);
  n=1000*n; n=(long)n;

  printf("%f %f\n",m,n);

  return 0;

Quote:
}




Tue, 18 Mar 1997 02:58:28 GMT  
 result of double*double is no double

 g> In the following code there is a difference in the output of m and n
 g> where I think shouldn't be one. The program prints (on Borland C
 g> DOS 3.1, IBM C-Set++ OS/2 and gcc 2.5.8 OS/2) the following:

 g> 1.332 1.333
    [from:]
 g> #include <stdio.h>

 g> int main(void)
 g> {
 g>   double m,n;

 g>   n=m=1.333;

 g>   m=(long)(1000*m);
 g>   n=1000*n; n=(long)n;

 g>   printf("%f %f\n",m,n);

 g>   return 0;
 g> }

 g> The problem here is apparently that the result of 1000*m is not a
 g> double internally. In the first case 1000*m is directly converted to
 g> a long whereas in the second case 1000*n is first stored in double n
 g> before being converted to a long.

This is a correct.

 g> I tried to switch off 'fast floating point' options on all
 g> compilers, but it didn't help. My question here is: Is this result
 g> conforming to the ANSI standard (I don't have it here)?

Yes, in my opinion.  ANSI 6.3.4 states "The values of floating operands and of
the results of floating expressions may be represented in greater precision and
range than that required by the type; the types are not changed thereby."

In BCC, the result of 1000*m is in internal 80-bit format, called long double
externally.  Casting to long causes that value to be converted.  In the case of
n, assignment rounds the value to double format (64-bit), which causes the
difference.

You can get 1.333 for m in BCC, with fast floating point option disabled, by
the following expression:

    m = (long)(double)(long double) (1000*m);

The long double cast causes the type of the expression to be long double.  The
cast to double then causes the same rounding as occurs with storage to n.  

If the cast to long double is omitted, (1000*m) has the long double
representation, but a type of double.  When it is cast to double, the standard
says "A cast that specifies no conversion has no effect on the type or value of
an expression." [ANSI 6.3.4] so no change in value can take place.

Disabling the BCC fast floating point option makes the compiler conforming in
this regard.

--
|Fidonet:  Thad Smith 1:104/825.14

|
| Standard disclaimer: The views of this user are strictly his own!
| From High Mountain Software & The Bailey Information Exchange BBS
| +1 303 674 0147, Bailey, Colorado, USA 1200-14400 Baud 8N1 24 Hrs
| Gateway Info: Fidonet: 1:104/825.0 (.10), Internet Domain: hms.com



Wed, 19 Mar 1997 21:21:25 GMT  
 result of double*double is no double


Quote:
>In the following code there is a difference in the output of m and n
>where I think shouldn't be one. The program prints (on Borland C DOS 3.1,
>IBM C-Set++ OS/2 and gcc 2.5.8 OS/2) the following:

>1.332 1.333

The compiler may store intermediate results at a higher precision so this
is perfectly valid.

--
-----------------------------------------


-----------------------------------------



Fri, 21 Mar 1997 01:21:23 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. can long double be less precise than double?

2. Problem with Double.IsNan() and Double.Nan

3. epsilon for float, double long double

4. Difference between double and long double?

5. Converting long double to double

6. double != double best way [Q]

7. 80bit double from mac to 64bit double to pc

8. View double* as array of double?

9. Internal structure of long double and double

10. diff between double and long double

11. Double Double

12. Comparing double NAN with double INF is not IEEE compliant

 

 
Powered by phpBB® Forum Software