round()函数的文档指出,您向其传递了一个数字,并将小数点后的位置传递给四舍五入。 因此,它应该这样做:
1 2
| n = 5.59
round(n, 1) # 5.6 |
但是,实际上,老的浮点怪异现象不断蔓延,您会得到:
出于UI的目的,我需要显示5.6。 我在Internet上闲逛,发现一些文档取决于我对Python的实现。 不幸的是,这在我的Windows开发机和我尝试过的每台Linux服务器上都会发生。 另请参阅此处。
除了创建自己的回合库之外,还有什么办法可以解决?
格式化无需四舍五入即可正确进行:
我不知道它的存储方式,但至少格式化正确:
1
| '%.1f' % round(n, 1) # Gives you '5.6' |
如果使用小数模块,则可以不使用"舍入"功能进行近似计算。这是我用于舍入的内容,尤其是在编写货币应用程序时:
1
| Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP) |
这将返回一个十进制数为16.20。
round(5.59, 1)工作正常。问题在于5.6无法精确地用二进制浮点表示。
1 2 3
| >>> 5.6
5.5999999999999996
>>> |
正如Vinko所说,您可以使用字符串格式对显示进行四舍五入。
如果需要,Python有一个用于十进制算术的模块。
如果执行str(round(n, 1))而不是round(n, 1),则将得到5.6。
您可以将数据类型切换为整数:
1 2 3 4 5
| >>> n = 5.59
>>> int(n * 10) / 10.0
5.5
>>> int(n * 10 + 0.5)
56 |
然后通过插入语言环境的小数点分隔符来显示数字。
但是,吉米的答案更好。
浮点数学运算容易出现轻微但令人讨厌的精度误差。如果可以使用整数或定点,则可以保证精度。
看一下Decimal模块
Decimal"is based on a floating-point
model which was designed with people
in mind, and necessarily has a
paramount guiding principle –
computers must provide an arithmetic
that works in the same way as the
arithmetic that people learn at
school." – excerpt from the decimal
arithmetic specification.
和
Decimal numbers can be represented
exactly. In contrast, numbers like 1.1
and 2.2 do not have an exact
representations in binary floating
point. End users typically would not
expect 1.1 + 2.2 to display as
3.3000000000000003 as it does with binary floating point.
Decimal提供了一种操作类型,可以轻松编写需要浮点运算的应用程序,并且还需要以人类可读的格式(例如会计)显示这些结果。
确实是个大问题。试用以下代码:
1
| print"%.2f" % (round((2*4.4+3*5.6+3*4.4)/8,2),) |
显示4.85。然后,您执行以下操作:
1
| print"Media = %.1f" % (round((2*4.4+3*5.6+3*4.4)/8,1),) |
它显示4.8。您手动计算的确切答案是4.85,但是如果尝试:
1
| print"Media = %.20f" % (round((2*4.4+3*5.6+3*4.4)/8,20),) |
您会看到事实:浮点存储为分母为2的幂的分数的最接近有限和。
打印吸盘。
1
| print '%.1f' % 5.59 # returns 5.6 |
您可以使用字符串格式运算符%,类似于sprintf。
1
| mystring ="%.2f" % 5.5999 |
完美的作品
1 2
| format(5.59, '.1f') # to display
float(format(5.59, '.1f')) #to round |
我在做:
在这种情况下,我们首先在单位级别正确舍入,然后转换为整数以避免打印浮点数。
所以
1 2
| >>> int(round(5.59,0))
6 |
我认为这个答案比格式化字符串更好,并且使用round函数对我也更有意义。
码:
1 2 3 4
| x1 = 5.63
x2 = 5.65
print(float('%.2f' % round(x1,1))) # gives you '5.6'
print(float('%.2f' % round(x2,1))) # gives you '5.7' |
输出:
问题仅在最后一位数字为5时出现。 0.045在内部存储为0.044999999999999 ...您可以将最后一位数字简单地增加到6并四舍五入。这将为您提供所需的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| import re
def custom_round(num, precision=0):
# Get the type of given number
type_num = type(num)
# If the given type is not a valid number type, raise TypeError
if type_num not in [int, float, Decimal]:
raise TypeError("type {} doesn't define __round__ method".format(type_num.__name__))
# If passed number is int, there is no rounding off.
if type_num == int:
return num
# Convert number to string.
str_num = str(num).lower()
# We will remove negative context from the number and add it back in the end
negative_number = False
if num < 0:
negative_number = True
str_num = str_num[1:]
# If number is in format 1e-12 or 2e+13, we have to convert it to
# to a string in standard decimal notation.
if 'e-' in str_num:
# For 1.23e-7, e_power = 7
e_power = int(re.findall('e-[0-9]+', str_num)[0][2:])
# For 1.23e-7, number = 123
number = ''.join(str_num.split('e-')[0].split('.'))
zeros = ''
# Number of zeros = e_power - 1 = 6
for i in range(e_power - 1):
zeros = zeros + '0'
# Scientific notation 1.23e-7 in regular decimal = 0.000000123
str_num = '0.' + zeros + number
if 'e+' in str_num:
# For 1.23e+7, e_power = 7
e_power = int(re.findall('e\+[0-9]+', str_num)[0][2:])
# For 1.23e+7, number_characteristic = 1
# characteristic is number left of decimal point.
number_characteristic = str_num.split('e+')[0].split('.')[0]
# For 1.23e+7, number_mantissa = 23
# mantissa is number right of decimal point.
number_mantissa = str_num.split('e+')[0].split('.')[1]
# For 1.23e+7, number = 123
number = number_characteristic + number_mantissa
zeros = ''
# Eg: for this condition = 1.23e+7
if e_power >= len(number_mantissa):
# Number of zeros = e_power - mantissa length = 5
for i in range(e_power - len(number_mantissa)):
zeros = zeros + '0'
# Scientific notation 1.23e+7 in regular decimal = 12300000.0
str_num = number + zeros + '.0'
# Eg: for this condition = 1.23e+1
if e_power < len(number_mantissa):
# In this case, we only need to shift the decimal e_power digits to the right
# So we just copy the digits from mantissa to characteristic and then remove
# them from mantissa.
for i in range(e_power):
number_characteristic = number_characteristic + number_mantissa[i]
number_mantissa = number_mantissa[i:]
# Scientific notation 1.23e+1 in regular decimal = 12.3
str_num = number_characteristic + '.' + number_mantissa
# characteristic is number left of decimal point.
characteristic_part = str_num.split('.')[0]
# mantissa is number right of decimal point.
mantissa_part = str_num.split('.')[1]
# If number is supposed to be rounded to whole number,
# check first decimal digit. If more than 5, return
# characteristic + 1 else return characteristic
if precision == 0:
if mantissa_part and int(mantissa_part[0]) >= 5:
return type_num(int(characteristic_part) + 1)
return type_num(characteristic_part)
# Get the precision of the given number.
num_precision = len(mantissa_part)
# Rounding off is done only if number precision is
# greater than requested precision
if num_precision <= precision:
return num
# Replace the last '5' with 6 so that rounding off returns desired results
if str_num[-1] == '5':
str_num = re.sub('5$', '6', str_num)
result = round(type_num(str_num), precision)
# If the number was negative, add negative context back
if negative_number:
result = result * -1
return result |
这是我看到回合失败的地方。如果要将这两个数字四舍五入到小数点后该怎么办?
23.45
23.55
我的教育是,通过四舍五入,您应该得到:
23.4
23.6
"规则"是,如果前面的数字为奇数,则应四舍五入,如果前面的数字为偶数,则不四舍五入。
python中的round函数将截断5。
关于什么: