0

Here's a C code;

#include<stdio.h>
#include<math.h>
int main()
{
    double n=10.0;
    double automatic = pow(10.0,log10(n)-log10(5.0));
    printf("%.9lf\n",log10(n)-log10(5.0));
    printf("%.9lf\n",pow(10.0,0.30102996));
    double manual = pow(10.0,0.30102996);
    printf("%.9lf %lf\n",automatic, floor(automatic));
    printf("%.9lf %lf\n",manual,floor(manual));
    return 0;
}

Output is:

0.301029996
1.999999836
2.000000000 1.000000
1.999999836 1.000000

From output I can infer that in pow(x,y) y is rounded off to 6 digits because it's signature is as pow(double x, double y) so that 0.301029996 becomes 0.301030 and that's why value of automatic is 2.000000000 otherwise it would be same as manual.

My questions:

  1. Is my inferation correct?
  2. If answer to first question is true then how can we bypass this rounding-off to achieve more accurate results?
Jeroen
  • 1,168
  • 1
  • 12
  • 24
Bharat Kul Ratan
  • 985
  • 2
  • 12
  • 24

1 Answers1

3

pow does not round to 6 digits. It uses double precision, which for an IEEE double is 52 bits of significand (roughly 15 decimal places). It may or may not be accurate to the last digit at that precision, but it's usually close.

The exact value of the base-10 log of 2 is close to 0.301029995663981195213738894724 (source: Wolfram Alpha). It is an irrational number, and so cannot be exactly represented by any digit system (decimal or binary).

Your results show that log10(n)-log10(5.0) has returned a value that's closer to the exact mathematical base-10 log of 2, than 0.30102996 is. The reason you got 1.999999836 is that you manually made your value less accurate when you replaced it with 0.30102996. Which isn't the rounded value, btw - count the 9s.

Your call pow(10.0,log10(n)-log10(5.0)) has returned a result which is very slightly less than 2 (as show by the floor), but close enough that it rounds to 2 at 9 places. You are not going to get better than this using the double type.

So I don't really know what you mean by "avoid the rounding off". If you don't want to make the value less accurate, don't manually round it to 9 places, and certainly don't miss out any digits when you copy it ;-)

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • I got your point; so it means that value of automatic is 2.000000000 because of printf. In actual it's not 2 but still is 1.99999... – Bharat Kul Ratan Aug 12 '12 at 15:26
  • @tendua: yes, it's somewhere from 1.9999999995 to 2. If you print `2.0 - pow(10.0,log10(n)-log10(5.0))` then you should see the magnitude of the error, although I think it's possible you'll get 0. Depends on whether the compiler lets the FPU use better-than-double precision for intermediate results. – Steve Jessop Aug 12 '12 at 15:35