Python 向下舍入到自定义步骤

Fra*_*nkC 5 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

###########################
Run Code Online (Sandbox Code Playgroud)

我们该如何解决它?

AKX*_*AKX 5

你会想要使用Decimal对象来获取精确的十进制数。

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

from decimal import Decimal, ROUND_DOWN

quantity = 0.00725562

step_size = Decimal("0.000001")
print(Decimal(quantity).quantize(step_size, ROUND_DOWN))
Run Code Online (Sandbox Code Playgroud)

打印出来

0.007255
Run Code Online (Sandbox Code Playgroud)


Tho*_*sse 2

这个 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%'
Run Code Online (Sandbox Code Playgroud)

对于你的例子:

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
Run Code Online (Sandbox Code Playgroud)