0

I have the following code :

func(double val) {
   // I am trying with the following values. both of which are in the range as per  
   // IEEE 754 std.
   // val = 1.847474
   int temp = [some_val = (1 << 23)];
   double temp2 = val * temp;
   printf("the produt111a = %15f\n",temp2);
}

value in temp2 results in loss of precision.

However, if I directly substitute the value of val while doing multiplication I got the correct result.

What can be done to avoid precision loss in such a scenario?

Dexter
  • 1,299
  • 3
  • 20
  • 38
  • 1
    You can't do anything. Floating-point arithmetic is not exact. – user3447428 Mar 25 '14 at 09:10
  • You need to understand the limitations of floating point arithmetic before you write any more code that uses it: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Paul R Mar 25 '14 at 09:10
  • Yes, SSCCE is needed. I trust you are aware that double precision arithmetic uses binary representations of numbers and inherently has limited precision. Perhaps your expectations are not realistics. – David Heffernan Mar 25 '14 at 09:10
  • I don't get it. You calculate the product of `int temp` and `double val`, store it inside `double temp2`. Then you print the `temp` as a `double`, why? And if you print `temp2` as a `double` the result should be precise enough, it is precise enough on my end at least (i.e. I see no incorrect digits at all). – Utkan Gezer Mar 25 '14 at 09:27
  • GCC 4.8.2 complains: `error: expected expression before '[' token int temp = [some_val = (1 << 23)];` – Peter G. Mar 25 '14 at 09:35
  • If `double` is to imprecise for you, use a more precice data type. – Peter G. Mar 25 '14 at 09:37
  • This is not exact working code. I edited it. You need to remove the some_val statement and assign it the value. – Dexter Mar 25 '14 at 09:38
  • @Dexter Still, `1.847474 * 2 ^ 23` equals `15497735.176192` according to my calculator, and I get the exact same result with the code you've given. – Utkan Gezer Mar 25 '14 at 09:39
  • @ThoAppelsin: This maybe because while using printf it sets the precision value to 15f. Between i am using gcc 4.1.2 – Dexter Mar 25 '14 at 09:41
  • @Dexter `15` you put there is not a precision value, rather width specification. If you want to use it as a precision value, then put `.15` with a dot behind. I am using MSVC 2013, and again, it displays the exact same result as my calculator. `2 ^ 23` is an integer, so the product with that and a decimal number with 6 digits after the decimal point may not have more decimal points than 6. `.15` therefore, should only display trailing zeroes until there are 15 digits after the decimal point. In that case, however, it rather displays `15497735.176192001000000` with a wild `1`. – Utkan Gezer Mar 25 '14 at 09:58
  • @ThoAppelsin : i get the result as 15497736 :( – Dexter Mar 25 '14 at 10:00
  • By default a `%f` substitute will get displayed with 6 digits after the decimal point, even if they all are just zero `0`. You must be doing something else than what you've shown to us, if you are having that number as the output. – Utkan Gezer Mar 25 '14 at 10:06
  • @ThoAppelsin : This is just a snippet of a big piece of code that i am working on. Essentially, this is the trouble area and the behavior for me is same as i have indicated. – Dexter Mar 25 '14 at 10:22
  • 1
    @Dexter - You need to update the posted code so that it runs and reproduces the problem you think you are seeing. You can test your little snippet of code at ideone.com. There is **no** precision loss upon multiplying some number by a power of two with a binary IEEE floating point representation. There is precision loss with `val = 1.847474`. The number 1.847474 cannot be represented exactly in an binary IEEE floating point representation. – David Hammen Mar 25 '14 at 11:28
  • 1
    You can't represent 0.1 exactly in binary any more than you can 1/3 in decimal. No implementation will fix either one. – duffymo Mar 25 '14 at 12:04
  • @Dexter Use `"%.16e"` to see the full _precision_ of `temp2`. http://stackoverflow.com/questions/16839658/printf-width-specificer-to-maintain-precision-of-floating-point-value/19897395#19897395 – chux - Reinstate Monica Mar 25 '14 at 13:49
  • possible duplicate of [How computer does floating point arithmetic?](http://stackoverflow.com/questions/6033184/how-computer-does-floating-point-arithmetic) – Blazemonger Mar 25 '14 at 14:23

1 Answers1

5

Precision is the (relative) difference from one floating point number to the next.

Accuracy is the (relative) difference between the numerical result and the exact result.

Multiplication with a power of 2 changes the exponent part of the floating point number and leaves the mantissa bits unchanged (see also the earlier comment by David Hammen). Thus there should be neither a loss in relative precision (still the same f.p. number type) nor in relative accuracy. Except in cases where you are very close to numerical over- or underflow.

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51