python实现精确的四舍五入
由于计算精度的问题,python无法实现真正的四舍五入
round四舍五入时是遵循靠近0原则,所以-0.5和0.5进行0位四舍五入,返回的都是0
round(2.135, 2) --> 2.13
round(number[, ndigits])
Return the floating point value number rounded to ndigits digits after the decimal point. If ndigits is omitted, it returns the nearest integer to its input. Delegates to number.round(ndigits).
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2). The return value is an integer if called with one argument, otherwise of the same type as number.
Note:
The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
def round5up(number, ndigits: int = 0):
"""
实现精确四舍五入,包含正、负小数多种场景
:param number: 数字类型
:param ndigits: 四舍五入位数,支持0-∞
:return: float
"""
if isinstance(number, int):
return number
multiplier = 10 ** ndigits
floor_number = int(number * multiplier)
if number >= 0:
if ndigits > 0:
factor = number * multiplier - floor_number + 1 / (multiplier * 10)
else:
factor = number * multiplier - floor_number
if factor >= 0.5:
return (floor_number + 1) / multiplier
else:
return floor_number / multiplier
else:
if ndigits > 0:
factor = number * multiplier - floor_number - 1 / (multiplier * 10)
else:
factor = number * multiplier - floor_number
if factor <= -0.5:
return (floor_number - 1) / multiplier
else:
return floor_number / multiplier
2.135 --> 2.14
2.625 --> 2.63
2.625 --> 2.625
-0.235 --> -0.24
2.699 --> 2.7
2.02499 --> 2.02
2.42599 --> 2.0
2.99599 --> 3.0
2.60599 --> 3.0
666 --> 666