0

This is a very noob question, but I am curious to know the reason behind this: -If I debug the following C++ code:

void floatreturn(float i){
      //nothing
}

int main(){
    float a = 23.976;
    floatreturn(a);
    return 0;
}

Monitoring the passed value of a, it appears to be 23.9759998 when entering floatreturn. As a result, any processing of the value in the function would require to manually tweak the precision. Is there a reason for this, and any way to avoid it?

mv_p
  • 3
  • 2
  • What's the change? The decimal part is obviously not going to be `23.976`, but I don't notice any change even when switching to `double`. https://ideone.com/7NgWb0 – silverfox Nov 24 '21 at 04:35
  • 3
    See https://stackoverflow.com/q/588004/5987. – Mark Ransom Nov 24 '21 at 04:36
  • 1
    `23.976` is a double, not float. Use `float a = 23.976f;` instead. But you'll never get the exactly result in binary floating point – phuclv Nov 24 '21 at 05:47
  • Try to represent `0.976` as a binary fraction, and you'll see the representation is infinite (the same reason that the fraction one-third in decimal has an infinite representation of `0.3` with the `3` repeating forever). So neither `0.976` nor `23.976` can be exactly represented in any floating point type (with a base-2 mantissa) and a nearest approximation is stored. On your platform, the nearest approximation represented by a `float` is apparently what you are seeing. (There is also a minor wrinkle that `23.976` has type `double`, and more precision may be lost on converting to `float`) – Peter Nov 24 '21 at 08:35

1 Answers1

1

The issue happened before floatreturn(a);.
It happened at float a = 23.976;
floatreturn(a); is irrelevant.

There are about 2^32 different values that float can encode exactly. 23.976 is not one of them. The nearest encodable float is about 23.9759998...

To avoid, use values that can exactly encode as a float or tolerate being close - about 1 part in 224

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thanks Mark for the link and chux for the concise answer. – mv_p Nov 24 '21 at 06:21
  • Just one more educational point for me: why does cout default to a precision of 3 decimals if we reprint the variable without setting precision for the output? I get that storing the float will always return the closest binary float possible, and that cout is rounding. – mv_p Nov 24 '21 at 06:23
  • @mv_p What was the _exact_ output you saw? – chux - Reinstate Monica Nov 24 '21 at 15:02
  • with a simple 'float x = 23.976; cout << x;' I see "23.976" – mv_p Nov 25 '21 at 04:31