What is a concise way to test if floating point value is integral?

Paul Jurczak pauljurczak at yahoo.com
Thu Aug 29 01:58:00 PDT 2013


On Thursday, 29 August 2013 at 08:26:11 UTC, Jonathan M Davis 
wrote:
> On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:
>> On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
>> wrote:
>> [..]
>> 
>> > as any integral value in a float will fit in an
>> > int.
>> 
>> [..]
>> 
>> Will it? Most of them will not fit
>
> Sure, they will. float has 32 bits, just like int, so it can't 
> possibly hold a
> value larger than an int can hold. This code passes with flying 
> colors
>
>     foreach(i; int.min .. int.max)
>         assert(cast(float)i == i);
>
>> but cast to int produces
>> nonsensical value anyway as in this example:
>> 
>> cast(int)float.max
>
> So what? All you care about here is whether the value in the 
> float is an
> integral value. float.max isn't an integral value, so it really 
> doesn't matter
> if you get overflow when converting. It would have to convert 
> back to the exact
> same value when converting it back to a float, and it won't.
>
> assert(cast(int)float.max == float.max);
>
> will fail. It might make more sense to use to!int if you want 
> to use the
> resulting int for something, but all you're doing with it is 
> comparing it
> against the original float to see if it's the same value. If 
> anything, the fact
> that to!int throws would be a serious problem for what you're 
> trying to do,
> because if what you're testing for is whether a float holds an 
> integral value,
> throwing on overflow when converting to int would just get in 
> your way. It
> should just result in false in that case (because it's not an 
> integral value,
> or it wouldn't overflow), and the cast will result in false, 
> unlike to!int.
>
> - Jonathan M Davis

I should have used "integer" instead of "integral" to avoid math 
vs. programming language confusion.

Well, float.max is an integer number! Its value is 3.40282e+38. 
The function I defined at the top of this page:

bool isIntegral(T)(T x) {return x == round(x);}

works correctly with float.max. Using cast(int) fails. I should 
have written it as:

bool isInteger(T)(T x) {return x == round(x);}



More information about the Digitalmars-d-learn mailing list