Python 向下舍入到自定义步骤



我们有一个部分工作的代码和 2 个具有不同类型的自定义步骤的示例。示例 2 (Int( 正常工作,而示例 1 则不工作,因为它向上舍入而不是向下舍入。

import math
def step_size_to_precision(ss):
return ss.find('1') - 1
def format_value(val, step_size_str):
precision = step_size_to_precision(step_size_str)
if precision > 0:
return "{:0.0{}f}".format(val, precision)
return math.floor(int(val))

###########################
# # example 1
step_size = "0.00000100"
quantity = 0.00725562
print(quantity)
print(format_value(quantity, step_size))
# 0.00725562
# 0.007256  <= Is rounding up instead of down. Should be 0.007255 
###########################
# # example 2
# step_size = "1"
# quantity = 3.00725562
# print(quantity)
# print(format_value(quantity, step_size))
# returns 3 <= This is correct
###########################

我们如何解决它?

您需要使用Decimal对象来获得精确的十进制数字。

然后,在ROUND_DOWN模式下使用Decimal.quantize()

from decimal import Decimal, ROUND_DOWN
quantity = 0.00725562
step_size = Decimal("0.000001")
print(Decimal(quantity).quantize(step_size, ROUND_DOWN))

打印输出

0.007255

SO 答案中概述了另一种方法:

如果要始终向下舍入(而不是四舍五入到最接近的 精度(,然后显式地使用math.floor()功能:

from math import floor
def floored_percentage(val, digits):
val *= 10 ** (digits + 2)
return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)
print floored_percentage(0.995, 1)
Demo:
>>> from math import floor
>>> def floored_percentage(val, digits):
...     val *= 10 ** (digits + 2)
...     return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)
... 
>>> floored_percentage(0.995, 1)
'99.5%'
>>> floored_percentage(0.995, 2)
'99.50%'
>>> floored_percentage(0.99987, 2)
'99.98%'

对于您的示例:

import math
def step_size_to_precision(ss):
return max(ss.find('1'), 1) - 1
def format_value(val, step_size):
digits = step_size_to_precision(step_size)
val *= 10 ** digits
return '{1:.{0}f}'.format(digits, math.floor(val) / 10 ** digits)

step_size = "0.00000100"
quantity = 0.00725562
print(quantity)
print(format_value(quantity, step_size))
# prints out: 0.007255

一种更通用的方法,允许向下舍入step_size,而不仅仅是 10 的幂:

from decimal import Decimal
def floor_step_size(quantity, step_size):
step_size_dec = Decimal(str(step_size))
return float(int(Decimal(str(quantity)) / step_size_dec) * step_size_dec)

用法:

>>> floor_step_size(0.00725562, "0.00000100")
0.007255
>>> floor_step_size(3.00725562, "1")
3.0
>>> floor_step_size(2.6, "0.25")
2.5
>>> floor_step_size(0.9, "0.2")
0.8

最新更新