Python向下舍入到自定义步骤

时间:2018-08-17 12:21:30

标签: python rounding

我们有部分工作代码和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

###########################

我们如何解决?

3 个答案:

答案 0 :(得分:2)

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

然后,在Decimal.quantize()中使用ROUND_DOWN mode

from decimal import Decimal, ROUND_DOWN

quantity = 0.00725562

step_size = Decimal("0.000001")
print(Decimal(quantity).quantize(step_size, ROUND_DOWN))

打印出

0.007255

答案 1 :(得分:2)

this SO answer中概述了另一种方法:

  

如果您想始终舍入 (而不是舍入到最接近的值)   精度),然后使用math.floor() function明确地这样做:

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

答案 2 :(得分:0)

一种更通用的方法,它允许对 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