繁体   English   中英

使用此双精度值四舍五入到特定位数失败

[英]Rounding to specfic digits fails with this double-precision value

我正在尝试截断C#中的一系列双精度值。 无论我使用哪种舍入方法,以下值都会失败。 导致这两种方法均失败的该值有什么问题? 为什么连Math.Round不能正确截断数字? 可以使用哪种方法正确截断这些值?

价值 :

double value = 0.61740451388888251;

方法1:

return Math.Round(value, digits);

方法2:

double multiplier = Math.Pow(10, decimals)
return Math.Round(value * multiplier) / multiplier;

即使在VS监视窗口中也失败!

回合

Double是浮点二进制点类型。 它们以二进制系统表示(例如11010.00110 )。 当十进制表示双精度数时,这只是一个近似值,因为并非所有二进制数字都以十进制表示精确。 例如,尝试以下操作:

double d = 3.65d + 0.05d;

它不会导致3.7而是3.6999999999999997 这是因为变量包含最接近的double

同样的情况发生在您的情况下。 您的变量包含最接近的double

对于精确操作, double / float不是最幸运的选择。 当您需要快速的性能或想在更大范围的数字上进行操作(但不需要高精度)时,请使用double / float 例如,它是物理计算的理想类型。 对于精确的小数运算,请使用decimal

这是有关float / decimal的文章: http : //csharpindepth.com/Articles/General/FloatingPoint.aspx

根据提供双精度表示的二进制表示形式的在线工具,最接近0.62的两个double值为:

6.19999999999999995559107901499E-10x3FE3D70A3D70A3D7 链接

6.20000000000000106581410364015E-10x3FE3D70A3D70A3D8 链接

我不确定为什么这些都不完全符合您的价值,但是就像其他人所说的那样,这很可能是浮点表示问题。

如果需要数字的更精确表示,则可能必须使用decimal类型,该类型精度更高但范围更小(通常使用财务计算)。

有关何时使用它们的更多信息,请参见: https : //stackoverflow.com/a/618596/1373170

我认为您正在遇到双精度浮点数(64位)的二进制限制。 http://en.wikipedia.org/wiki/Double-precision_floating-point_format中 ,双精度数仅给出15-17个有效数字。

暂无
暂无

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

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