Precision loss from float to double, and from double to float?
Asked Answered
P

1

12
float fv = orginal_value;  // original_value may be any float value
...
double dv = (double)fv;
...
fv = (float)dv;

SHOULD fv be equal to original_value exactly? Any precision may be lost?

Pe answered 25/4, 2016 at 12:9 Comment(8)
Possible duplicate ? #3498692Espino
Thanks for your comments. I think it is different. the question backend is: I want to store a float(32bit) value to double(64bit) for simplicity, but after some procedure, restore the original float value from the double stored value. in the issue you mentioned, I only see it mentioned to convert from double to float)Pe
What is the type of original_value ?Linton
Are you asking for C or C++?Viradis
For this question, any difference between C and C++?Pe
@ravin.wang: I'm slightly thrown off by your use of SHOULD. are you asking whether or not a double to float demotion is without risks in general, or only in specific cases?Encephalon
@EliasVanOotegem I am writing a general function, all float and double values are stored in a double field, but when getting it in some other place, I'd like to restore its original value.Pe
Original value != original type... but if you're going to operate on a value, demoting to float from double is a bad ideaEncephalon
V
20

SHOULD fv be equal to original_value exactly? Any precision may be lost?

Yes, if the value of dv did not change in between.

From section Conversion 6.3.1.5 Real Floating types in C99 specs:

  1. When a float is promoted to double or long double, or a double is promoted to long double, its value is unchanged.
  2. When a double is demoted to float, a long double is demoted to double or float, or a value being represented in greater precision and range than required by its semantic type (see 6.3.1.8) is explicitly converted to its semantic type, if the value being converted can be represented exactly in the new type, it is unchanged. If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation-defined manner. If the value being converted is outside the range of values that can be represented, the behavior is undefined

For C++, from section 4.6 aka conv.fpprom (draft used: n337 and I believe similar lines are available in final specs)

A prvalue of type float can be converted to a prvalue of type double. The value is unchanged. This conversion is called floating point promotion.

And section 4.8 aka conv.double

A prvalue of floating point type can be converted to a prvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined. The conversions allowed as floating point promotions are excluded from the set of floating point conversions

So the values should be equal exactly.

Viradis answered 25/4, 2016 at 12:19 Comment(2)
It's important to note that, what the OP added as ... lines in the snippet should not change the value of dv, if it does, loss of precision or even UB might followEncephalon
Initial "SHOULD fv be equal to original_value exactly? Any precision may be lost?" are 2 questions and answer "Yes" only applies to the first one - It appears you want "no" to the 2nd question. Suggest small edit to clarify.Ramsgate

© 2022 - 2024 — McMap. All rights reserved.