# Most Efficient Way to Check a Variable Is A Whole Number

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 05-25-2009
bengreenwood
Most Efficient Way to Check a Variable Is A Whole Number
Hi,

I have a question. Say you have a variable of type double, and you want to check if it is a whole number or not. What is the most efficient way to do this? At present I am doing something like this, but it doesn't seem very efficient.

Code:

```#include <iostream> using namespace std; int main() {     double a_dbl = 3.5;     int a_int = static_cast<int>(a_dbl);     if (a_dbl == a_int)         cout << "a_dbl is a whole number";     else         cout << "a_dbl is not a whole number"; }```
Thanks guys.
• 05-25-2009
Brafil
I think "static_cast<int>(a_dbl) == 3". (Probably rounded down)
Why is it inefficient?
• 05-25-2009
Litz
The cast will round it down as it basically cuts off the decimal part of the number.
The code seems fine though.
• 05-25-2009
matsp
What sort of "efficiency" are you asking for - performance (e.g. smaller or faster code), or simply "easier to type in" efficient?

If you need to do A HUGE number of "is this a whole number", then you may want to use optimized code. But if you simply want to know if it's OK to do it this way, I'd say it's as good as you can get.

There are problems converting numbers to integer and back to float if they are borderline the range that the floating point type can hold. For example, a float will run out of precision at about 2^23. So if you have a number that is more than 32 million (or less than -32 million), then it won't match precisely.

A double can hold 2^53 bits, so it's a fairly huge value before it starts loosing precision, but it's possible if you are counting very large amounts (national debts and such things).

--
Mats
• 05-25-2009
iMalc
It is both inefficient and fails for anything but a fairly small range with respect to the actual range of a double. 10 billion isn't a whole number with that code!
The correct way to do it would be:
Code:

`    if (a_dbl == floor(a_dbl))`
Or you can just as easily use 'ceil' if you prefer, which is 1 character shorter.
• 05-25-2009
bengreenwood
I thought it might be inefficient because it's using an int variable as well as the original double. ie I thought it would be more efficient not to use the extra one.

BTW if I use if
Code:

`(a_dbl == floor(a_dbl))`
do I need to include another header file for that?

Thanks.
• 05-25-2009
matsp
Quote:

Originally Posted by bengreenwood
I thought it might be inefficient because it's using an int variable as well as the original double. ie I thought it would be more efficient not to use the extra one.

BTW if I use if
Code:

`(a_dbl == floor(a_dbl))`
do I need to include another header file for that?

Thanks.

You need math.h, which you probably need if you are doing anything but simple math problems.

--
Mats
• 05-26-2009
Daved
Be careful when using == to compare floating point numbers. See these FAQ entries:

[29.16] Why is floating point so inaccurate? Why doesn't this print 0.43?
[29.17] Why doesn't my floating-point comparison work?

For example, on my machine, the following code:
Code:

```#include <iostream> #include <cmath> int main() {   float a = 1000.43f;   float b = 1000.0f;   float c = a - b;  // 0.43   float d = c*100.f;  // 43     if (d == std::floor(d))         std::cout << d << " is equal to " << std::floor(d) << ", so it is a whole number!!\n";     else         std::cout << d << " is not equal to " << std::floor(d) << ", so it is NOT a whole number!!\n"; }```
outputs the wrong answer:
Code:

`42.9993 is not equal to 42, so it is NOT a whole number!!`
Whether you get the same result depends on your compiler, but seemingly simple computation can give the incorrect answer if you're not careful.
• 05-26-2009
brewbuck
If we make the reasonable assumption that floating point values can precisely represent integer values (a likely, but by no means guaranteed assumption), then there are myriad ways to do this, most of which have already been mentioned.

As far as which is more efficient, any one of the proposed methods: conversion to integer, ceil, floor, other rounding -- is going to involve a processor-specific sequence of instructions whose performance can't be predicted in advance. What is most efficient on one processor may be less efficient on another, even between revisions of the same basic line of CPU.
• 05-26-2009
iMalc
If the problem is changed to "Is this close enough to a whole number" then one solution is this:
Code:

`    if (fabs(a_dbl - std::floor(a_dbl)) < EPSILON || fabs(a_dbl - std::ceil(a_dbl)) < EPSILON)`
Where EPSILON is a value that is chosen to be suitable for the floating point representation being used.
The expression may be able to be simplified though.
• 05-26-2009
grumpy
Quote:

Originally Posted by Daved
Be careful when using == to compare floating point numbers.

While, in general, I agree with you ..... it's not necessary to worry when comparing x and floor(x) if it is necessary to detect that a floating point variable x holds an integral value.

However, in practice, if the value is being read from a user (eg as input from stdin) it would be better to read a string and then interpret the content of the string to see if it represents an integral value. That eliminates concerns with rounding of floating point values. The basic procedure to do this would be

1) If there is a decimal point, count the number of digits after the decimal point.

2) Extract the exponent, if any (eg 1.3E2 has an exponent of 2).

3) Take the difference. If result is positive, the value is not integral.

Examples

100 0 after decimal, 0 exponent. Result: 0 i.e. integral
0.1 1 after decimal, 0 exponent. Result 1: i.e. non-integral.
0.1E2 1 after decimal, 2 exponent Result -1 i.e. integral
100E-3 0 after decimal, -3 exponent. Result 3 i.e. non-integral.

There is the anomaly that converting input to a floating point variable can give different results (eg integral input looks like a non-integer and vice versa). But, in practice, I've never needed to detect if a floating point variable x holds an integral value - if such a test is needed, it's normally because of a need to understand intent of a user .... hence parsing user input is best.
• 05-26-2009
Daved
>> it's not necessary to worry when comparing x and floor(x) if it is necessary to detect that a floating point variable x holds an integral value.

What about my example? It gives incorrect output.
• 05-26-2009
abachler
Code:

```bool CheckIfWhole(double Input){   return (Input == (signed long long)Input);   }```
• 05-26-2009
iMalc
Quote:

Originally Posted by abachler
Code:

```bool CheckIfWhole(double Input){   return (Input == (signed long long)Input);   }```

Less likely to be a problem of course, but a double still far exceeds the range of a long long. So 2^100 (which is exactly representable in a double) isn't a whole number with that approach.
But then you probably already knew that.
• 05-26-2009
SyntaxError
You could also tying doing something like calling frexp, left shifting the result by the exponent part and then testing for 0. I'm not sure if it's any faster though.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last