所以我有以下代码
int main(){
double d;
cin>>d;
while(d!=0.00)
{
cout<<d<<endl;
double m = 100*d;
int n = m;
cout<<n<<endl;
cin>>d;
}
return 0;}
当我为d输入输入20.40时,n的值为2039而不是2040。
我尝试用int n = m
替换int n = (int) m
,但结果是一样的。
有没有什么办法解决这一问题。提前谢谢。
答案 0 :(得分:3)
您的代码会截断m,但您需要舍入。包括cmath
并使用int n = round(m)
。
答案 1 :(得分:2)
通常,十进制值不能使用像double
这样的二进制浮点精确表示。因此,值20.40
被表示为近似值,其可用于恢复原始值(20.4
;精度不能保留),例如,在格式化值时。使用这些近似值进行计算通常会放大误差。
正如其中一篇评论中已经提到的,相关参考文献是paper“每个计算机科学家应该知道的关于浮点算术的内容”。解决问题的一种可能方法是使用十进制浮点数,但这不是{+ 3}} C ++标准的一部分。
答案 2 :(得分:1)
单和双预设浮点数的存储方式与整数的存储方式不同,因此整数(例如5,10)实际上可能看起来像长小数(例如4.9999001,10.00000000001)。当你转换为int
时,它只会截断整数。因此,如果该号码目前被表示为4.999999999
,则将其投放到int
会给您4
。 std::round
会在大多数情况下为您提供更好的结果(如果数字是4.6而您只想要整数部分,则圆形将无法正常工作)。那么更大的问题是:你希望通过将double
投射到int
来实现什么目标?
通常,在处理浮点数时,您需要使用一些 epsilon 值,这是您的最小有效数字。所以如果你想比较4.9999999到5,你会做(伪代码):if abs(5 - 4.9999999) < epsilon, return 5
。
示例强>
int main()
{
double d;
std::cin >> d;
while (std::fabs(d - 0.0) > DBL_EPSILON)
{
std::cout << d << std::endl;
double m = 100 * d;
int n = static_cast<int>(m);
if (std::fabs(static_cast<double>(n) - m) > DBL_EPSILON)
{
n++;
}
std::cout << n << std::endl;
std::cin >> d;
}
return 0;
}
答案 3 :(得分:0)
将double转换为int截断值,因此20.40可能是20.399999 * 100是2039.99,因为double不是基数10.您可以使用不会截断但最接近int的round()函数。
int n = round(m);
答案 4 :(得分:0)
浮点数不能精确表示所有十进制数,有时会使用近似值。在您的示例中,最接近的确切数字是20.39999999999999857891452847979962825775146484375。有关查看确切值的快速方法,请参阅IEEE-754 Analysis。
你可以使用舍入,但可能你真的在寻找截断的前两位数字。只需添加一个非常小的值,例如在乘以之前或之后0.0000000001。