我正在尝试将十进制数字舍入到最接近的0.05。现在,我这样做:
add_action('init', function()
{
add_rewrite_rule('^guides/?$', 'index.php?post_type=guides', 'top');
});
有没有什么方法可以更优雅地做到这一点而不用使用python Decimals处理浮点数(也许使用量化)?
答案 0 :(得分:7)
使用浮点数,只需使用round(x * 2, 1) / 2
即可。但是,这并不能控制舍入方向。
使用Decimal.quantize
,您还可以完全控制舍入的类型和方向(Python 3.5.1):
>>> from decimal import Decimal, ROUND_UP
>>> x = Decimal("3.426")
>>> (x * 2).quantize(Decimal('.1'), rounding=ROUND_UP) / 2
Decimal('3.45')
>>> x = Decimal("3.456")
>>> (x * 2).quantize(Decimal('.1'), rounding=ROUND_UP) / 2
Decimal('3.5')
答案 1 :(得分:0)
首先注意这个问题(意外的四舍五入)只有 有时 才会发生,当你正在四舍五入的数字紧邻(左边)的数字有{ {1}}。
即
5
但是有一个简单的解决方案,我发现它似乎始终有效,而且不依赖于>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01
的其他库。解决方案是添加import
,其中1e-X
是您尝试在加号X
上使用round
的数字字符串的长度。
1
啊哈!因此,基于此,我们可以创建一个方便的包装函数,它是独立的,不需要额外的>>> round(0.075,2)
0.07
>>> round(0.075+10**(-2*6),2)
0.08
调用......
import
基本上,这会增加一个值,保证小于您尝试使用def roundTraditional(val,digits):
return round(val+10**(-len(str(val))-1))
的字符串的最小给定数字。通过添加少量数量,它在大多数情况下保留了round
的行为,同时现在确保数字低于被舍入的数字是round
它是否会向上舍入,如果是{{1}它向下舍入。
使用5
的方法是故意的,因为它是您可以添加的最大小数字以强制转换,同时还确保您添加的值永远不会更改舍入,即使小数4
不见了。我可以使用10**(-len(val)-1)
与条件.
一起减去10**(-len(val))
更多......但更简单的是总是减去if (val>1)
,因为这不会改变很多适用此变通方法可以正确处理的十进制数范围。如果您的值达到类型的限制,此方法将失败,这将失败,但对于几乎整个有效小数值范围,它应该有效。
您也可以使用decimal库来完成此任务,但我建议的包装器更简单,在某些情况下可能更受欢迎。
答案 2 :(得分:0)
适用于任何舍入基数的更通用的解决方案。
from decimal import ROUND_DOWN
def round_decimal(decimal_number, base=1, rounding=ROUND_DOWN):
"""
Round decimal number to the nearest base
:param decimal_number: decimal number to round to the nearest base
:type decimal_number: Decimal
:param base: rounding base, e.g. 5, Decimal('0.05')
:type base: int or Decimal
:param rounding: Decimal rounding type
:rtype: Decimal
"""
return base * (decimal_number / base).quantize(1, rounding=rounding)
示例:
>>> from decimal import Decimal, ROUND_UP
>>> round_decimal(Decimal('123.34'), base=5)
Decimal('120')
>>> round_decimal(Decimal('123.34'), base=6, rounding=ROUND_UP)
Decimal('126')
>>> round_decimal(Decimal('123.34'), base=Decimal('0.05'))
Decimal('123.30')
>>> round_decimal(Decimal('123.34'), base=Decimal('0.5'), rounding=ROUND_UP)
Decimal('123.5')