Losing precision when multiplying Doubles in C

2019-08-05 15:42发布

问题:

I am trying to get multiplay decimal part of a double number about 500 times. This number starts to lose precision as time goes on. Is there any trick to be able to make the continued multiplication accurate?

double x = 0.3;
double binary = 2.0;

for (i=0; i<500; i++){
    x = x * binary;
    printf("x equals to : %f",x);
    if(x>=1.0)
        x = x - 1;
}

Ok after i read some of the things u posted i am thinking how could i remove this unwanted stuff from my number to keep multiplication stable. For instance in my example. My decimal parts will be chaning in such manner: 0.3,0.6,0.2,0.4,0.8... Can we cut the rest to keep this numbers ??

回答1:

With typical FP is binary64, double x = 0.3; results in x with the value more like 0.29999999999999998890... so code has an difference from the beginning.

Scale x by 10 to stay with exact math - or use a decimal64 double

int main(void) {
  double x = 3.0;
  double binary = 2.0;
  printf("x equals to : %.20f\n",x);
  for (int i=0; i<500; i++){
      x = x * binary;
      printf("x equals to : %.20f\n",x/10);
      if(x>=10.0)
          x = x - 10;
  }
  return 0;
}


回答2:

In general, floating point math is not completely precise, as shown in the other answers and in many online resources. The problem is that certain numbers can not be represented exactly in binary. 0.3 is such a number, but all natural numbers aren't. So you could change your program to this:

double x = 3.0;
double binary = 2.0;

for (i=0; i<500; i++){
    x = x * binary;
    printf("x equals to : %f",x/10.0);
    if(x>=10.0)
        x = x - 10.0;
}


回答3:

Although your program is doing some very unusual things, the main answer to your question is that that is how floating point numbers work. They are imprecise.

http://floating-point-gui.de/basic/