问题
I have a variable x
of type float
, and I need its fractional part. I know I can get it with
x - floorf(x)
, orfmodf(x, 1.0f)
My questions: Is one of these always preferable to the other? Are they effectively the same? Is there a third alternative I might consider?
Notes:
- If the answer depends on the processor I'm using, let's make it x86_64, and if you can elaborate about other processors that would be nice.
- Please make sure and refer to the behavior on negative values of
x
. I don't mind this behavior or that, but I need to know what the behavior is.
回答1:
Is there a third alternative I might consider?
There's the dedicated function for it. modff exists to decompose a number into its integral and fractional parts.
float modff( float arg, float* iptr );
Decomposes given floating point value
arg
into integral and fractional parts, each having the same type and sign asarg
. The integral part (in floating-point format) is stored in the object pointed to byiptr
.
回答2:
I'd say that x - floorf(x)
is pretty good (exact), except in corner cases
- it has the wrong sign bit for negative zero or any other negative whole float (we might expect the fraction part to wear the same sign bit).
- it does not work that well with inf
modff does respect -0.0 sign bit for both int and frac part, and answer +/-0.0 for +/-inf fraction part - at least if implementation supports the IEC 60559 standard (IEEE 754).
A rationale for inf could be: since every float greater than 2^precision has a null fraction part, then it must be true for infinite float too.
That's minor, but nonetheless different.
EDIT Err, of course as pointed by @StoryTeller-UnslanderMonica the most obvious flaw of x - floor(x)
is for the case of negative floating point with a fraction part, because applied to -2.25, it would return +0.75 for example, which is not what we expect...
Since c99 label is used, x - truncf(x)
would be more correct, but still suffer from the minor problems onto which I initially focused.
来源:https://stackoverflow.com/questions/65576961/how-should-i-obtain-the-fractional-part-of-a-floating-point-value