简体   繁体   English

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

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

I'm attempting to truncate a series of double-precision values in C#. 我正在尝试截断C#中的一系列双精度值。 The following value fails no matter what rounding method I use. 无论我使用哪种舍入方法,以下值都会失败。 What is wrong with this value that causes both of these methods to fail? 导致这两种方法均失败的该值有什么问题? Why does even Math.Round fail to correctly truncate the number? 为什么连Math.Round不能正确截断数字? What method can be used instead to correctly truncate such values? 可以使用哪种方法正确截断这些值?

The value : 价值 :

double value = 0.61740451388888251;

Method 1: 方法1:

return Math.Round(value, digits);

Method 2: 方法2:

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

Fails even in VS watch window! 即使在VS监视窗口中也失败!

回合

Double is a floating binary point type. Double是浮点二进制点类型。 They are represented in binary system (like 11010.00110 ). 它们以二进制系统表示(例如11010.00110 )。 When double is presented in decimal system it is only an approximation as not all binary numbers have exact representation in decimal system. 当十进制表示双精度数时,这只是一个近似值,因为并非所有二进制数字都以十进制表示精确。 Try for example this operation: 例如,尝试以下操作:

double d = 3.65d + 0.05d;

It will not result in 3.7 but in 3.6999999999999997 . 它不会导致3.7而是3.6999999999999997 It is because the variable contains a closest available double . 这是因为变量包含最接近的double

The same happens in your case. 同样的情况发生在您的情况下。 Your variable contains closest available double . 您的变量包含最接近的double

For precise operations double / float is not the most fortunate choice. 对于精确操作, double / float不是最幸运的选择。 Use double / float when you need fast performance or you want to operate on larger range of numbers, but where high precision is not required. 当您需要快速的性能或想在更大范围的数字上进行操作(但不需要高精度)时,请使用double / float For instance, it is perfect type for calculations in physics. 例如,它是物理计算的理想类型。 For precise decimal operations use, well, decimal . 对于精确的小数运算,请使用decimal

Here is an article about float / decimal : http://csharpindepth.com/Articles/General/FloatingPoint.aspx 这是有关float / decimal的文章: http : //csharpindepth.com/Articles/General/FloatingPoint.aspx

According to this online tool which gives the binary representation of doubles, the two closest double values to 0.62 are: 根据提供双精度表示的二进制表示形式的在线工具,最接近0.62的两个double值为:

6.19999999999999995559107901499E-1 or 0x3FE3D70A3D70A3D7 link 6.19999999999999995559107901499E-10x3FE3D70A3D70A3D7 链接

6.20000000000000106581410364015E-1 or 0x3FE3D70A3D70A3D8 link 6.20000000000000106581410364015E-10x3FE3D70A3D70A3D8 链接

I'm not sure why neither of these agree with your value exactly, but like the others said, it is likely a floating point representation issue. 我不确定为什么这些都不完全符合您的价值,但是就像其他人所说的那样,这很可能是浮点表示问题。

If you need a more exact representation of the number you might have to use the decimal type, which has more precision but smaller range (it's usually used financial calculations). 如果需要数字的更精确表示,则可能必须使用decimal类型,该类型精度更高但范围更小(通常使用财务计算)。

More info on when to use each here: https://stackoverflow.com/a/618596/1373170 有关何时使用它们的更多信息,请参见: https : //stackoverflow.com/a/618596/1373170

I think you are running up against the binary limit of a double-precision float (64 bits). 我认为您正在遇到双精度浮点数(64位)的二进制限制。 From http://en.wikipedia.org/wiki/Double-precision_floating-point_format , a double only gives between 15-17 significant digits. 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