C ++确定数字是否为整数

时间:2013-10-26 23:33:18

标签: c++ int double decimal

我在C ++中有一个程序,我将两个数字分开,我需要知道答案是否为整数。我正在使用的是:

  

if(fmod(answer,1)== 0)

我也试过这个:

  

如果(地板(回答)==回答)

问题是答案通常是一个5位数,但有很多小数。例如,answer可以是:58696.000000000000000025658,程序认为是整数。

有什么方法可以让我的工作吗?

我正在划分double a/double b= double answer

(有时小数超过30)

谢谢!

编辑: a和b是数千(约100,000)的数字,然后被提升到2和3的幂,加在一起并分开(根据复杂的公式)。所以我插入各种a和b值并查看答案。我只保留使得答案为整数的a和b值。我得到的一个答案的一个例子是:218624,我的程序上面认为是一个整数,但它确实是:218624.00000000000000000056982所以我需要一个能够区分超过20-30位小数的整数的代码。

3 个答案:

答案 0 :(得分:1)

您可以在std::modf中使用cmath.h

double integral;
if(std::modf(answer, &integral) == 0.0)

answer的整数部分存储在fraction中,std::modf的返回值是answer的小数部分,其符号与answer相同

答案 1 :(得分:1)

通常的解决方案是检查数字是否在整数的非常短的距离内,如下所示:

bool isInteger(double a){
    double b=round(a),epsilon=1e-9; //some small range of error
    return (a<=b+epsilon && a>=b-epsilon); 
}

这是必需的,因为浮点数的精度有限,而且确实是整数的数字可能无法完美表示。例如,如果我们进行直接比较,以下内容将失败:

double d=sqrt(2); //square root of 2
double answer=2.0/(d*d); //2 divided by 2

这里,answer实际上保持值0.99999...,因此我们无法将其与整数进行比较,我们无法检查小数部分是否接近0。 通常,由于数字的浮点表示可以比实际数字小一点或略大一点,因此检查小数部分是否接近0是不好的。它可能是{{1 }}或0.99999999(甚至是他们的否定),这些都是精确损失的可能结果。这也是我检查双方(0.000001+epsilon)的原因。您应该调整-epsilon变量以满足您的需求。

另外,请注意epsilon的精确度接近15 digits。您也可以使用double,这可能会为您提供一些额外的精度数字(或者不是,这取决于编译器),但即使这样也只能让您获得18 digits。如果您需要更高的精度,则需要使用外部库,如GMP

答案 2 :(得分:-1)

浮点数使用与整数非常不同的位格式存储在内存中。因此,将它们与平等进行比较不太可能有效。相反,您需要测试差异是否小于某些 epsilon

const double EPSILON = 0.00000000000000000001; // adjust for whatever precision is useful for you
double remainder = std::fmod(numer, denom);
if(std::fabs(0.0 - remainder) < EPSILON)
{
    //...
}

或者,如果要包含接近整数的值(基于所需的精度),可以稍微修改if条件(因为std::fmod返回的余数将在{{1}范围内}}):

[0, 1)

您可以看到此here的测试。

浮点数通常有些精确到大约12-15位数(作为if (std::fabs(std::round(d) - d) < EPSILON) { // ... } ),但由于它们存储为尾数(分数)和指数,有理数(整数或常用分数)是不太可能存储。例如,

double

因此,您需要将您期望的差异与包含您所需精度的一些非常小的数字进行比较(我们将此值称为 epsilon ):

double d = 2.0; // d might actually be 1.99999999999999995

因此,当您尝试比较double d = 2.0; bool test = std::fabs(2 - d) < epsilon; // will return true 的余数时,您需要根据std::fmod的差异(不是实际相等到0.0)来检查它,这是什么在上面完成。

此外,0.0调用阻止您通过断言值始终为正数来进行2次检查。

如果您希望精度大于15-18位小数,则无法使用std::fabsdouble;您将需要使用高精度浮点库。