double 类型的舍入问题
可能的重复:
为什么对双精度值的运算不能给出预期的结果结果?
我在 C++ 中遇到了一个特殊的问题。我创建了一个 Double 类型的变量。然后我用分配给其他变量的一些值进行了一些计算,并将结果分配给我声明的双变量。它给了我一个带有长小数部分的结果。我希望它四舍五入到小数点后两位。并将其存储到变量中。但即使经过多次尝试四舍五入,我也无法将其四舍五入到小数点后两位。
然后我尝试了另一种方法来检查真正的问题是什么。我创建了一个 Double 变量并为其指定了值 1.11。但是当我通过设置断点并添加该变量的监视来调试它时,我可以发现现在存储在变量中的值是 1.109999999999。
我的问题是,为什么会这样显示?有没有什么方法可以将变量四舍五入到小数点后两位?即使我们分配的数字只有两位小数,为什么它仍显示很长的小数部分?
请建议一种存储数字的方法 - 无论是计算的还是直接分配的 - 按原样存储在双精度变量中,而不是具有长小数部分的数字中。
Possible Duplicate:
Why don't operations on double-precision values give expected results?
I am experiencing a peculiar problem in C++. I created a variable of type Double. Then I did some calculations with some values assigned to other variables and assigned the result to the double variable I declared. It gave me a result with a long decimal part. I want it to round to only 2 decimal places. and store it into the variable. But even after several attempt rounding, I couldnt round it to 2 decimal places.
Then I tried another way to check what the real problem is. I created a Double variable and assigned it the value 1.11. But when I debugged it by putting a break point and added a watch for that variable, I could find that the value now stored in the variable is 1.109999999999.
My question is, why is it showing like that? Isnt there any way in which we can round the variable into two decimal places? Why is it showing a long decimal part even if we assign a number with just two decimal places?
Please suggest a way to store numbers - whether it is calculated or directly assigned - as it is, in a double variable rather than a number with a long decimal part.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 double 值集中,不存在数字 1.11 这样的东西,因为 double 在内部使用二进制表示形式(而不是人类习惯的十进制表示形式)。大多数有限十进制数(例如 1.11)在二进制中具有无限表示形式,但由于内存有限,因此会因舍入而损失一些精度。
使用 double 数据类型可以得到的最接近 1.11 的值是 1.1100000000000000976996261670137755572795867919921875,其内部表示为 0x3ff1c28f5c28f5c3。
您对小数点后两位的要求听起来像是您正在与金钱打交道。一个简单的解决方案是将美分存储为整数(而不是将美元存储为双精度):
这样,您就不会丢失任何精度。另一种解决方案是使用专用的十进制数据类型。
In the set of double values, there is no such thing as the number 1.11 because internally, double uses a binary representation (as opposed to humans who are used to a decimal representation). Most finite decimal numbers (such as 1.11) have an infinite representation in binary, but since memory is limited, you lose some precision because of rounding.
The closest you can get to 1.11 with the double data type is 1.1100000000000000976996261670137755572795867919921875, which is internally represented as 0x3ff1c28f5c28f5c3.
Your requirement of two decimal places sounds like you are working with money. A simple solution is to store the cents in an integer (as opposed to the dollars in a double):
This way, you don't lose any precision. Another solution is to use a dedicated decimal data type.
float 和 double 等浮点类型并不是 100% 精确。他们可能会将 14.3 存储为 14.299999...这没有任何问题。这就是为什么你永远不应该用 == 运算符比较两个浮点数或双精度数,相反你应该检查它们差异的绝对值是否小于某个 epsilon,比如 0.000000001
现在,如果你想以一种愉快的方式输出数字,您可以使用
中的set precision
例如,
如果您想获得 d 的值,四舍五入到小数点后 2 位,那么您可以使用此公式
the floating-point types like float and double are not 100% precise. They may store 14.3 as 14.299999... and there is nothing wrong about that. That is why you should NEVER compare two floats or doubles with == operator, instread you should check if the absolute value of their difference is smaller than a certain epsilon, like 0.000000001
Now, if you want to output the number in a pleasant way, you can use
setprecision
from<iomanip>
E.g.
If you want to obtain the value of d rounded 2 decimal places after the point, then you can use this formula
并非每个十进制数都有精确的、有限的、二进制浮点表示。您已经找到了一个示例,但另一个示例是 0.1(十进制)= 0.0001100110011...(二进制)。
您要么需要忍受这一点,要么使用十进制浮点库(效率较低)。
我的建议是完全精确地存储数字,并且仅在需要向人类显示它们时进行舍入。
Not every decimal number has an exact, finite, binary floating-point representation. You've already found one example, but another one is 0.1 (decimal) = 0.0001100110011... (binary).
You either need to live with that, or use a decimal floating-point library (which will be less efficient).
My recommendation would be to store numbers to full precision, and only round when you need to display them to humans.