我正在用python开发应用程序,其中一些部分用c#编写(以加快速度),而我困惑为什么在使用“ round”函数和字符串浮点时,c#浮点舍入与python表现为“相反”格式化功能,下面是一个示例:
Python(2.7)
>>> round(6.25, 1)
6.3
>>> "%.1f"%6.25
6.2
C#
>>> Math.Round(6.25,1)
6.2
>>> (6.25).ToString("F1")
6.3
有人知道为什么Python与C#之间的行为看起来“相反”吗?有没有办法将“双”浮点值舍入为N个十进制数字,以在Python和C#之间产生保证相同的字符串输出?
答案 0 :(得分:3)
这是由于您正在调用的两个方法的中点分辨率。
Python的round(number[, ndigits])
返回小数点后四舍五入为
ndigits
位的浮点数。如果省略ndigits
,则默认为零。结果是一个浮点数。值四舍五入到与幂减ndigits
相乘的10的最接近倍数;如果两个倍数相等地接近,则四舍五入要远离0
(例如,round(0.5)
是1.0
,而round(-0.5)
是-1.0
)。>
将双精度浮点值四舍五入为指定数量的小数位数,并将中点值四舍五入为最接近的偶数。
换句话说:
6.25
变为6.3
,因为6.3
比0
离6.2
更远)6.25
成为6.2
,因为6.2
是最接近的偶数。您可以通过使用MidpointRounding
enum value之类的Math.Round
重载之一来解决此问题,例如Round(double, int, MidpointRounding)
,例如:
Math.Round(6.25, 1, MidpointRounding.AwayFromZero);
与Python取整功能相同。
答案 1 :(得分:2)
引用Banker's Rounding。
它是有目的的实现细节。
如果您希望保留“始终向上舍入0.5向上”方法或您希望使用的任何其他舍入方法,则可以执行以下操作:
import decimal
#The rounding you are looking for
decimal.Decimal('3.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
>>> Decimal('4')
decimal.Decimal('2.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
>>> Decimal('3')
#Other kinds of rounding
decimal.Decimal('2.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_EVEN)
>>> Decimal('2')
decimal.Decimal('3.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_DOWN)
>>> Decimal('3')
答案 2 :(得分:1)
Math.Round
默认使用银行家的四舍五入,四舍五入到最接近的偶数值(例如,如您所见,Math.Round(6.25,1)
-> 6.2,以及Math.Round(6.35,1)
-> 6.4)。要更改此设置,请使用MidpointRounding值,例如Math.Round(6.25, 1, MidpointRounding.AwayFromZero)
。
对于另一个问题,double.ToString()会导致舍入。有关此问题的解决方法,请参见C# Double - ToString() formatting with two decimal places but no rounding。