I'm fixing some lint errors in a codebase I am working with, and I see the following line
// note offset is int64_t, scale is int64_t, x is double
int64_t y = offset lrintf(scale * static_cast<float>(x))
the linter complains and says
narrowing conversion from 'int64_t' (aka 'long') to 'float'
.
It seems the scale * static_cast<float>(x)
is what's causing issues, and I'm wondering what is the best way to handle this error? should I cast scale
to a double, and then call lrintd
instead? Or is there a better approach for this case?
CodePudding user response:
You're right. The static_cast
discards some bits from the mantissa and exponent. This also limits the number of bits in the mantissa of float(scale)
.
Note that a typical IEEE754 double
also has insufficient bits in the mantissa to fully express every int64_t
value. That's logical: both are 8 byte types. But float is only 4 bytes in IEEE754.
CodePudding user response:
Seems more logical to use
int64_t y = offset llrint(scale * x);
scale * x
will be double
and should be rounded to long long
(AKA int64_t
).
Note anyway that this might modify the program behavior in some cases (truncating the double
to float
or not could result in different y
).