繁体   English   中英

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

[英]C++ determining if a number is an integer

我有一个用C ++编写的程序,其中我将两个数相除,我需要知道答案是否为整数。 我正在使用的是:

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

我也试过这个:

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

问题是答案通常是5位数字,但有许多小数。 例如,答案可以是: 58696.000000000000000025658 ,并且程序认为该整数。

有什么办法可以使这项工作吗?

我将double a/double b= double answer

(有时超过30个小数)

谢谢!

编辑:a和b是数以千计(约100,000),然后将其提高为2和3的幂,相加并相除(根据一个复杂的公式)。 因此,我插入各种a和b值并查看答案。 我只会保留使答案成为整数的a和b值。 我得到一个答案的例子是:218624,上面的程序认为它是整数,但实际上是:218624.00000000000000000056982因此,我需要一个可以区分具有20-30个以上十进制小数的整数的代码。

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

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

answer的整数部分存储在fractionstd::modf的返回值是answer的分数部分,其符号与answer相同。

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

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。它可能是0.999999990.000001 (甚至它们的负数)之类的数字,这些都是精度损失的可能结果。 这就是为什么我要同时检查两面( +epsilon-epsilon )。 您应该调整该epsilon变量以适合您的需求。

另外,请记住, double精度的精度接近15位数 您还可以使用long double精度数,这可能会给您带来一些额外的精度数字(或者不是,这取决于编译器),但是即使这样也只能使您达到18位数左右。 如果您需要的精度更高,则需要使用外部库,例如GMP

浮点数使用与整数非常不同的位格式存储在内存中。 因此,比较它们的平等性不太可能有效。 相反,您需要测试差异是否小于某个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返回的余数将在[0, 1)范围内):

if (std::fabs(std::round(d) - d) < EPSILON)
{
    // ...
}

您可以在此处查看此测试。

浮点数通常会精确到大约12至15位数(以double ),但由于它们以尾数(分数)存储,并且指数形式的有理数(整数或普通分数)不太可能这样存储。 例如,

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

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

double d = 2.0;
bool test = std::fabs(2 - d) < epsilon; // will return true

因此,当您尝试比较std::fmod的其余部分时,需要将其与0.0之差(不是实际等于0.0 )进行检查,这就是上面所做的。

同样, std::fabs调用通过断言该值始终为正值来防止您必须进行两次检查。

如果您希望精度达到小数点后15-18位,则不能使用doublelong double 您将需要使用高精度浮点库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM