Your function returns true by -1 , so it does not work. This is easy enough to fix, but your approach has other fundamental problems.
In any rounding mode, it will calculate either infinity or the largest normal number when applied to the smallest positive nonzero subnormal. Taking the product will lead to infinity or something significantly less than 1 .
In the mode from rounding to the point closest to it, true is also returned to double after 1 . (And many, many and many other double s.)
In round-up mode, let's say it works for positive, normal floating-point numbers; if x not a power of two, then 1/x cannot be represented exactly like flup(1/x) , the floating-point number to which 1/x rounded in circular mode is strictly greater than 1/x . Then x * flup(1/x)) strictly greater than x ; therefore, flup(x * flup(1/x)) strictly greater than 1. However, for a positive normal cardinality of two operations, both operations are exact. The same applies to the round and round to zero modes.
The following code appears in round-upward, round-downward, and round-to-zero modes for IEEE 754 double s:
int p2(double d) { return d > 0 && 0x1.0p-51 / d * d == 0x1.0p-51; }
The constant 0x1.0p-51 was chosen so that the sample 0x1.0p-51 / d * d did not overflow for the smallest subnormal or overflow for the largest normal power of two.
I can calculate d times the round error when dividing 0x1.0p-51 by d, which is of the order of 0x1.0p-104 . The following code works in all four rounding modes:
int p2(double d) { return d > 0 && fma(0x1.0p-51/d, d, -0x1.0p-51) == 0; }
With all this in mind, you should use Alan Stokes' solution; frexp designed for such things, and it behaves wisely in all strange cases.