C++ 检查双变量是否包含整数,而不是浮点数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1521607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check double variable if it contains an integer, and not floating point
提问by vehomzzz
What I mean is the following:
我的意思是:
double d1 =555;
double d2=55.343
I want to be able to tell that d1 is an integer while d2 is not. Is there an easy way to do it in c/c++?
我希望能够告诉 d1 是一个整数而 d2 不是。有没有一种简单的方法可以在 c/c++ 中做到这一点?
回答by avakar
Use std::modf
:
使用std::modf
:
double intpart;
modf(value, &intpart) == 0.0
Don't convert to int
! The number 1.0e+300
is an integer too you know.
不要转换为int
!这个数字1.0e+300
也是一个整数,你知道。
Edit: As Pete Kirkham points out, passing 0 as the second argument is not guaranteed by the standard to work, requiring the use of a dummy variable and, unfortunately, making the code a lot less elegant.
编辑:正如 Pete Kirkham 指出的那样,标准不保证将 0 作为第二个参数传递,需要使用虚拟变量,不幸的是,这使代码变得不那么优雅。
回答by TJ L
Assuming you have the cmath <math.h>
library, you can check the number against it's floor. If the number might be negative, make sure you get the absolutefirst.
假设您有 cmath<math.h>
库,您可以根据它的floor来检查数字。如果数字可能是负数,请确保首先获得绝对值。
bool double_is_int(double trouble) {
double absolute = abs( trouble );
return absolute == floor(absolute);
}
回答by Stephen Canon
Assuming a c99 and IEEE-754 compliant environment,
假设一个符合 c99 和 IEEE-754 的环境,
(trunc(x) == x)
is another solution, and will (on most platforms) have slightly better performance than modf
because it needs only to produce the integer part. Both are completely acceptable.
是另一种解决方案,并且(在大多数平台上)性能略好于modf
因为它只需要生成整数部分。两者都是完全可以接受的。
Note that trunc
produces a double-precision result, so you don't need to worry about out of range type conversions as you would with (int)x
.
请注意,trunc
会产生双精度结果,因此您无需像使用(int)x
.
Edit: as @pavonpoints out in a comment, you may need to add another check, depending on whether or not you care about infinity, and what result you want to get if x
is infinite.
编辑:正如@pavon在评论中指出的那样,您可能需要添加另一个检查,这取决于您是否关心无穷大,以及如果x
是无穷大,您想要得到什么结果。
回答by Pete Kirkham
avakar was almost right - use modf, but the detail was off.
avakar 几乎是正确的 - 使用 modf,但细节已关闭。
modf returns the fractional part, so the test should be that the result of modf is 0.0.
modf 返回小数部分,所以测试应该是 modf 的结果是 0.0。
modf takes two arguments, the second of which should be a pointer of the same type as the first argument. Passing NULL or 0 causes a segmentation fault in the g++ runtime. The standard does not specify that passing 0 is safe; it might be that it happens to work on avakar's machine but don't do it.
modf 接受两个参数,其中第二个参数应该是与第一个参数类型相同的指针。传递 NULL 或 0 会导致 g++ 运行时出现分段错误。该标准没有规定传递 0 是安全的;可能是它碰巧在 avakar 的机器上工作,但不要这样做。
You could also use fmod(a,b)
which calculates the a
modulo b
passing 1.0. This also should give the fractional part.
您还可以使用fmod(a,b)
which 计算通过a
1.0.0 的模数b
。这也应该给出小数部分。
#include<cmath>
#include<iostream>
int main ()
{
double d1 = 555;
double d2 = 55.343;
double int_part1;
double int_part2;
using namespace std;
cout << boolalpha;
cout << d1 << " " << modf ( d1, &int_part1 ) << endl;
cout << d1 << " " << ( modf ( d1, &int_part1 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d1 << " " << fmod ( d1, 1.0 ) << endl;
cout << d1 << " " << ( fmod ( d1, 1.0 ) == 0 ) << endl;
cout << d2 << " " << fmod ( d2, 1.0 ) << endl;
cout << d2 << " " << ( fmod ( d2, 1.0 ) == 0 ) << endl;
cout.flush();
modf ( d1, 0 ); // segfault
}
回答by DVK
How about
怎么样
if (abs(d1 - (round(d1))) < 0.000000001) {
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Fixed up to work using rounding to reflect bug Anna found
修复了使用舍入来反映 Anna 发现的错误的工作
Alternate solutions:
替代解决方案:
if ((d1 - floor(d1) < 0.000000001) || (d1 - floor(d1) > 0.9999999999)) {
/* Better store floor value in a temp variable to speed up */
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Theres also another one with taking floor, subtracting 0.5 and taking abs() of that and comparing to 0.499999999 but I figure it won't be a major performance improvement.
还有另一种使用发言权,减去 0.5 并取 abs() 并与 0.499999999 进行比较,但我认为这不会是重大的性能改进。
回答by DigitalRoss
int iHaveNoFraction(double d){
return d == trunc(d);
}
Now, it wouldn't be C if it didn't have about 40 years of language revisions...
现在,如果没有大约 40 年的语言修订,它就不会是 C...
In C, ==
returns int
but in C++ it returns bool
. At least on my Linux distro (Ubuntu) you need to either declare double trunc(double);
or you could compile with -std=c99
, or declare the level macro, all in order to get <math.h>
to declare it.
在 C 中,==
返回,int
但在 C++ 中,它返回bool
. 至少在我的 Linux 发行版 (Ubuntu) 上,您需要声明double trunc(double);
或者可以使用 编译-std=c99
,或者声明级别宏,所有这些都是为了<math.h>
声明它。
回答by Ashwin
How about this?
这个怎么样?
if ((d1 - (int)d1) == 0)
// integer
回答by Patrice Bernassola
try:
尝试:
bool isInteger(double d, double delta)
{
double absd = abs(d);
if( absd - floor(absd) > 0.5 )
return (ceil(absd) - absd) < delta;
return (d - floor(absd)) < delta;
}
回答by Kirill V. Lyadvinsky
#include <math.h>
#include <limits>
int main()
{
double x, y, n;
x = SOME_VAL;
y = modf( x, &n ); // splits a floating-point value into fractional and integer parts
if ( abs(y) < std::numeric_limits<double>::epsilon() )
{
// no floating part
}
}
回答by KJP
Below you have the code for testing d1 and d2 keeping it very simple. The only thing you have to test is whether the variable value is equal to the same value converted to an int type. If this is not the case then it is not an integer.
下面是测试 d1 和 d2 的代码,使其非常简单。您唯一需要测试的是变量值是否等于转换为 int 类型的相同值。如果不是这种情况,则它不是整数。
#include<iostream>
using namespace std;
int main()
{
void checkType(double x);
double d1 = 555;
double d2 = 55.343;
checkType(d1);
checkType(d2);
system("Pause");
return 0;
}
void checkType(double x)
{
if(x != (int)x)
{
cout<< x << " is not an integer "<< endl;
}
else
{
cout << x << " is an integer " << endl;
}
};