1 c++ double integer fractions fmodf
我有这个静态方法,它接收一个double并"切割"它的小数尾部,在点之后留下两位数.工程几乎所有的时间.我注意到当它收到2.3时它会变成2.29.0.3,1.3,3.3,4.3和102.3不会发生这种情况.代码基本上将数字乘以100使用modf将整数值除以100并返回它.这里代码捕获了这个特定的数字并打印出来:
static double dRound(double number) {
bool c = false;
if (number == 2.3)
c = true;
int factor = pow(10, 2);
number *= factor;
if (c) {
cout << " number *= factor : " << number << endl;
//number = 230;// When this is not marked as comment the code works well.
}
double returnVal;
if (c){
cout << " fractional : " << modf(number, &returnVal) << endl;
cout << " integer : " <<returnVal << endl;
}
modf(number, &returnVal);
return returnVal / factor;
}
Run Code Online (Sandbox Code Playgroud)
打印出来:
数字*=因子:230
分数:1
整数:229
有谁知道为什么会这样,我该如何解决这个问题?谢谢你,周末愉快.
请记住,浮点数不能完全代表十进制数.2.3*100实际上给出229.99999999999997.因此modf返回229和0.9999999999999716.
但是,cout默认情况下,格式只会将浮点数显示为6位小数.所以0.9999999999999716显示为1.
您可以(大致)使用浮点值表示的上限错误,以避免2.3错误:
#include <cmath>
#include <limits>
static double dRound(double d) {
double inf = copysign(std::numeric_limits<double>::infinity(), d);
double theNumberAfter = nextafter(d, inf);
double epsilon = theNumberAfter - d;
int factor = 100;
d *= factor;
epsilon *= factor/2;
d += epsilon;
double returnVal;
modf(number, &returnVal);
return returnVal / factor;
}
Run Code Online (Sandbox Code Playgroud)
结果:http://www.ideone.com/ywmua