C++;确定数字是否为整数 我有一个C++程序,我把两个数分开,我需要知道答案是不是整数。我使用的是:
如果(fmod(答案1)=0) 我也试过: 如果(楼层(回答)=回答) 问题是答案通常是5位数字,但有很多小数。例如,答案可以是:C++;确定数字是否为整数 我有一个C++程序,我把两个数分开,我需要知道答案是不是整数。我使用的是:,c++,int,double,decimal,C++,Int,Double,Decimal,如果(fmod(答案1)=0) 我也试过: 如果(楼层(回答)=回答) 问题是答案通常是5位数字,但有很多小数。例如,答案可以是:58696.0000000000000000 25658,程序认为这是一个整数 有什么办法可以让这一切顺利吗 我正在划分双a/双b=双答案 (有时小数位数超过30) 谢谢 编辑: a和b是以千(约100000)为单位的数字,然后将它们提升为2和3的幂,相加并除以(根据一个复杂的公式)。所以我插入不同的a和b值,看看答案。我将只保留使答案为整数的a和b值。其中一个答案的
58696.0000000000000000 25658
,程序认为这是一个整数
有什么办法可以让这一切顺利吗
我正在划分双a/双b=双答案
(有时小数位数超过30)
谢谢
编辑:
a和b是以千(约100000)为单位的数字,然后将它们提升为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
的整数部分存储在fraction
中,std::modf
的返回值是answer
的小数部分,其符号与answer
相同。浮点数使用与整数截然不同的位格式存储在内存中。正因为如此,比较它们是否平等不太可能有效。相反,您需要测试差异是否小于某个ε:
你可以看到这个测试
浮点数通常精确到大约12-15位(作为双精度),但由于它们存储为尾数(分数)和指数,有理数(整数或公共分数)不太可能存储为尾数。比如说,
double d = 2.0; // d might actually be 1.99999999999999995
因此,您需要将您期望的差异与包含您期望的精度的非常小的数字进行比较(我们将此值称为epsilon):
double d=2.0;
布尔检验=std::fabs(2-d)
因此,当您试图比较std::fmod
中的余数时,您需要检查它与0.0
(与0.0
)的差异,这是上面所做的
另外,std::fabs
调用通过断言值将始终为正值来防止您进行两次检查
如果希望精度大于15-18位小数,则不能使用
双精度
或长双精度
;您需要使用高精度浮点库。通常的解决方案是检查数字是否在整数的很短距离内,如下所示:
bool isInteger(double a){
double b=round(a),epsilon=1e-9; //some small range of error
return (a<=b+epsilon && a>=b-epsilon);
}
这里,answer
实际上包含值0.99999…
,因此我们无法将其与整数进行比较,也无法检查小数部分是否接近0。
一般来说,由于数字的浮点表示可以比实际数字小一点或大一点,因此检查小数部分是否接近0是不好的。它可能是一个类似于0.9999999
或0.000001
(甚至是它们的负数)的数字,这些都是精度损失的可能结果。这也是为什么我要检查两边(+epsilon
和-epsilon
)。您应该调整epsilon
变量以满足您的需要
此外,请记住,
double
的精度接近。您还可以使用长双精度
,这可能会给您一些额外的精度数字(或者不,这取决于编译器),但即使这样,也只能让您四处走动。如果您需要更高的精度,则需要使用外部库,例如。为什么要命名整型部分分数?@DwayneTowell可能是因为已经过了05:00,而我仍然醒着。谢谢编辑:)由于浮点数存储在内存中的方式,您不想执行==0.0
检查。相反,您需要执行std::modf(answer,&integral)
。这不提供请求的操作,即为接近整数的数字报告true。而且,即使在分数部分非常小的情况下修改为报告true,对于2.99999999999955591079014993738383054737332763671875这样的数字,它也会继续报告false,我怀疑OP更喜欢true。如果仅对略大于整数的数字报告true,而不对略小于整数的数字报告true,例如2.99999999995559107901499937383830547332763671875?有多少差异是可以接受的?你是怎么得到应该是整数还是不应该是整数的数字的(是什么先前的计算导致的)?您的a/b
示例中的a
和b
从何而来?a和b是以千为单位(约100000)的数字,然后将其提升为2和3的幂,相加并除以(根据复杂的公式)。所以我插入不同的a和b值,看看答案。我将只保留使答案为整数的a和b值。其中一个答案的一个例子是:218624,我上面的程序认为它是一个整数,但实际上是:218624.00000000000000000056982,所以我需要一个能区分20-30个小数点以上的整数的代码。@ItM你将无法用双精度来做到这一点。您需要使用高精度浮点库。我正在考虑GMP,但不知道如何使用它。218624.00万,000万000 5600 9822不能以大多数C++实现的格式表示为<代码>双< /代码>。
double d = 2.0; // d might actually be 1.99999999999999995
double d = 2.0;
bool test = std::fabs(2 - d) < epsilon; // will return true
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