如果double变量包含整数而不是浮点,则检查它

veh*_*zzz 39 c c++ floating-point

我的意思是:

  double d1 =555;
  double d2=55.343
Run Code Online (Sandbox Code Playgroud)

我希望能够告诉d1是一个整数而d2不是.有没有一种简单的方法在c/c ++中做到这一点?

ava*_*kar 71

用途std::modf:

double intpart;
modf(value, &intpart) == 0.0
Run Code Online (Sandbox Code Playgroud)

不要转换为int!1.0e+300你知道,这个数字也是一个整数.

编辑:正如Pete Kirkham所指出的那样,传递0作为第二个参数并不能保证标准工作,需要使用虚拟变量,不幸的是,使代码不那么优雅.

  • 我现在不知道`modf`已存在的util. (18认同)
  • 我认为你最好将modf返回值与epsilon而不是零进行比较 (6认同)
  • 事实上,传递0作为第二个参数不仅不能保证工作,而且会在许多平台上崩溃. (3认同)
  • 在具有IEEE-754算术的主机上任何模糊的modf实现将*始终*产生精确的小数部分.如果您的平台没有模糊的数学库实现,您应该坚持使用整数或(更好)找到一个新的平台. (3认同)
  • 同意.C标准库中的掘金+1.虽然我会使用`NULL`而不是`0`但我明白这是C++中一个相当有争议的问题,没有充分的理由. (2认同)
  • **请注意,此方法将 a ±∞ 视为整数。** 但是,您不需要用这个处理 `NaN`。 (2认同)

tj1*_*111 9

假设您有cmath <math.h>库,您可以根据它的楼层检查数字.如果数字可能是负数,请确保先获得绝对值.

bool double_is_int(double trouble) {
   double absolute = abs( trouble );
   return absolute == floor(absolute);
}
Run Code Online (Sandbox Code Playgroud)

  • 为了理智,我建议您重新考虑您对参数名称的选择. (8认同)
  • 我认为没有必要先转向绝对值。 (4认同)

Pet*_*ham 7

avakar 几乎是正确的 - 使用 modf,但细节已关闭。

modf 返回小数部分,所以测试应该是 modf 的结果是 0.0。

modf 接受两个参数,其中第二个参数应该是与第一个参数类型相同的指针。传递 NULL 或 0 会导致 g++ 运行时出现分段错误。该标准没有规定传递 0 是安全的;可能是它碰巧在 avakar 的机器上工作,但不要这样做。

您还可以使用fmod(a,b)which 计算通过a1.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

}
Run Code Online (Sandbox Code Playgroud)


Ste*_*non 6

假设符合c99和IEEE-754标准的环境,

(trunc(x) == x)
Run Code Online (Sandbox Code Playgroud)

是另一种解决方案,并且(在大多数平台上)将具有稍微好一点的性能,modf因为它只需要生成整数部分.两者都完全可以接受.

请注意,trunc会产生双精度结果,因此您无需担心超出范围类型的转换(int)x.


编辑:正如@pavon在评论中指出的那样,你可能需要添加另一张支票,具体取决于你是否关心无穷大,以及你想要得到的结果x是无限的.

  • @pavon:在 IEEE 754 中说无穷大是偶数几乎是合理的(因为所有足够大的浮点数都是偶数,所以无穷大“也应该是”;这是无稽之谈,但是吸引人的废话)。 (2认同)