03 March 2009

Precision of float calculations

Given that a and b are positive, the calculation:

a*b
and
exp(log(a)+log(b))
are mathematically the same.


But is this true in computer languages?

a:1.2345678e-30
b:5.5889944e-28
The real result is: 6.89999252062032 e-58
What do the following programs tell me?

C

#include <math.h>
#include <stdio.h>

int main(){
  double a = 1.2345678e-30;
  double b = 5.5889944e-28;
  double c, d;

  c = a * b;
  d = exp(log(a)+log(b));

  printf("a * b =                %.20e \n", c);
  printf("exp(log(a) + log(b)) = %.20e \n", d);
  return 0;
};

output:
a * b = 6.89999252062031977189e-58
exp(log(a) + log(b)) = 6.89999252062023345995e-58
The real result is: 6.89999252062032


Python

import math
a = 1.2345678e-30
b = 5.5889944e-28
print "----------math----------"
print "a * b =                %s" % repr(a*b)
print "exp(log(a) + log(b)) = %s" % repr(math.exp(math.log(a)+math.log(b)))



import mpmath
mpmath.mp.dps = 20
a = mpmath.mpf(1.2345678e-30)
b = mpmath.mpf(5.5889944e-28)
print "---------mpmath---------"
print "a * b =                %s" % repr(a*b)
print "exp(log(a) + log(b)) = %s" % repr(mpmath.exp(mpmath.log(a)+mpmath.log(b)))
output:
----------math----------
a * b = 6.8999925206203198e-58
exp(log(a) + log(b)) = 6.8999925206202335e-58
---------mpmath---------
a * b = mpf('6.8999925206203201922352e-58')
exp(log(a) + log(b)) = mpf('6.8999925206203201919869e-58')
The real result is: 6.89999252062032


Scheme

(define x 0.0000000000000000000000000000012345678)
(define y 0.00000000000000000000000000055889944)
(* x y)
(exp (+ (log x) (log y)))

output:
6.89999252062032e-58
6.899992520620233e-58


R

c = 1.2345678e-30 * 5.5889944e-28 print(c, digits=20) d = exp(log(1.2345678e-30) + log(5.5889944e-28)) print(d, digits=20)
output:
6.89999252062032e-58
6.899992520620233e-58
the real result is 6.89999252062032 e-58

gcalctool

Not exactly a language, but interesting: the result is 6.89999252062032e-58 for a*b.
Note, that the standard windows calculator also prints the exact result.

So what is the result:

Language Results
c: 6.89999252062031977189 e-58
6.89999252062023345995 e-58
python (math): 6.8999925206203198 e-58
6.8999925206202335 e-58
python (mpmath): 6.8999925206203201922352 e-58
6.8999925206203201919869 e-58
scheme: 6.89999252062032 e-58
6.899992520620233 e-58
R 6.89999252062032e-58
6.899992520620233e-58
gcalculator and windows calculator: 6.89999252062032 e-58
the real result: 6.89999252062032 e-58

comments powered by Disqus