python: round/format float/string 具体 decimal/fraction
python: round/format float/string to specific decimal/fraction
我在 python 中发现了很多关于四舍五入的帖子,但据我了解 none 到目前为止解决了我的问题。
我正在寻找的两个解决方案:
最接近的舍入:float/string 需要根据其大小进行不同舍入的数字。
向下舍入:float/string 数字需要根据其大小向下 进行不同的舍入。
四舍五入:float/string 需要四舍五入的数字 向上 取决于它们的大小。
示例:
- +500:0 位小数(整数)(例如,最接近的:500.5 -> 501;向下:500.99 -> 500;向上:500.01 -> 501)
- +100:1 位小数(分数:0.2)(例如,最近:100.29 -> 100.2;向下:100.39 -> 100.2;向上:100.21 -> 100.4)。因此,该值必须以 .0、.2、.4、.6 或 .8
结尾
- +5:2 位小数(分数:0.01)(例如,最近:5.019 -> 5.02;向下:5.019 -> 5.01;向上:5.011 -> 5.02)。因此,值必须以 .x0、.x1、.x2、.x3、.x4、.x5、.x6、.x7、.x8 或 .x9
结尾
结果变量应该是一个字符串。
我正在寻找的整洁的东西是一个函数,我可以在其中传递 小数位数 和 分数
这样的事情怎么样?
def round_accordingly(num):
if num>=500:
return str(round(num))
elif num>=100:
return str(round(num, 1))
elif num>=5:
return str(round(num, 2))
print(round_accordingly(550.73424))
print(round_accordingly(200.234245))
print(round_accordingly(7.564743))
您可以使用 Decimal module for highly customizable rounding:
import decimal
def rnd(f,n,r=decimal.ROUND_HALF_DOWN):
pat='1.'+'0'*n
return str(decimal.Decimal(str(f)).quantize(decimal.Decimal(pat),r))
现在开始测试:
for n in (500.99,100.39,5.019):
for i in (0,1,2):
print('n={:10}, i={:2}, Down: {:>10}, Closest: {:>10}'.format(n,i, rnd(n,i,decimal.ROUND_FLOOR),rnd(n,i)))
打印:
n= 500.99, i= 0, Down: 500, Closest: 501
n= 500.99, i= 1, Down: 500.9, Closest: 501.0
n= 500.99, i= 2, Down: 500.99, Closest: 500.99
n= 100.39, i= 0, Down: 100, Closest: 100
n= 100.39, i= 1, Down: 100.3, Closest: 100.4
n= 100.39, i= 2, Down: 100.39, Closest: 100.39
n= 5.019, i= 0, Down: 5, Closest: 5
n= 5.019, i= 1, Down: 5.0, Closest: 5.0
n= 5.019, i= 2, Down: 5.01, Closest: 5.02
(注意:这是 1 位小数和 100.39
输入的不同输出。请说明在这种情况下 100.2
的所需输出?输出不应该是 100.3
?)
经过澄清,我认为您只需要使用 fmod
:
import math
def rnd(n,f,prec,direction='down'):
if direction=='down':
if prec==0:
return str(int(n))
return str(round(n-math.fmod(n,f),prec))
else:
if prec==0:
return str(int(round(n)))
n+=f
return str(round(n-math.fmod(n,f),prec))
适用于给定的所有示例:
>>> rnd(500.99,0.1,0)
'500'
>>> rnd(500.99,0.1,0,'')
'501'
>>> rnd(100.39,0.2,1,'')
'100.4'
>>> rnd(100.39,0.2,1)
'100.2'
>>> rnd(100.59,0.2,1,'')
'100.6'
>>> rnd(100.59,0.2,1)
'100.4'
>>> rnd(5.019,0.01,2)
'5.01'
>>> rnd(5.019,0.01,2,'')
'5.02'
(使用 direction=
关键字参数和除 'down'
以外的任何字符串值调用函数以起床。根据您的喜好更改...)
编辑 2
这个returns最接近输入数字的方法:
def rnd(n,f,prec):
n1=int(n) if prec==0 else round(n-math.fmod(n,f),prec)
n2=float(int(round(n))) if prec==0 else round((n+f)-math.fmod((n+f),f),prec)
return str(min((n1,n2), key=lambda e: math.fabs(e-n)))
我在 python 中发现了很多关于四舍五入的帖子,但据我了解 none 到目前为止解决了我的问题。
我正在寻找的两个解决方案:
最接近的舍入:float/string 需要根据其大小进行不同舍入的数字。
向下舍入:float/string 数字需要根据其大小向下 进行不同的舍入。
四舍五入:float/string 需要四舍五入的数字 向上 取决于它们的大小。
示例:
- +500:0 位小数(整数)(例如,最接近的:500.5 -> 501;向下:500.99 -> 500;向上:500.01 -> 501)
- +100:1 位小数(分数:0.2)(例如,最近:100.29 -> 100.2;向下:100.39 -> 100.2;向上:100.21 -> 100.4)。因此,该值必须以 .0、.2、.4、.6 或 .8 结尾
- +5:2 位小数(分数:0.01)(例如,最近:5.019 -> 5.02;向下:5.019 -> 5.01;向上:5.011 -> 5.02)。因此,值必须以 .x0、.x1、.x2、.x3、.x4、.x5、.x6、.x7、.x8 或 .x9 结尾
结果变量应该是一个字符串。
我正在寻找的整洁的东西是一个函数,我可以在其中传递 小数位数 和 分数
这样的事情怎么样?
def round_accordingly(num):
if num>=500:
return str(round(num))
elif num>=100:
return str(round(num, 1))
elif num>=5:
return str(round(num, 2))
print(round_accordingly(550.73424))
print(round_accordingly(200.234245))
print(round_accordingly(7.564743))
您可以使用 Decimal module for highly customizable rounding:
import decimal
def rnd(f,n,r=decimal.ROUND_HALF_DOWN):
pat='1.'+'0'*n
return str(decimal.Decimal(str(f)).quantize(decimal.Decimal(pat),r))
现在开始测试:
for n in (500.99,100.39,5.019):
for i in (0,1,2):
print('n={:10}, i={:2}, Down: {:>10}, Closest: {:>10}'.format(n,i, rnd(n,i,decimal.ROUND_FLOOR),rnd(n,i)))
打印:
n= 500.99, i= 0, Down: 500, Closest: 501
n= 500.99, i= 1, Down: 500.9, Closest: 501.0
n= 500.99, i= 2, Down: 500.99, Closest: 500.99
n= 100.39, i= 0, Down: 100, Closest: 100
n= 100.39, i= 1, Down: 100.3, Closest: 100.4
n= 100.39, i= 2, Down: 100.39, Closest: 100.39
n= 5.019, i= 0, Down: 5, Closest: 5
n= 5.019, i= 1, Down: 5.0, Closest: 5.0
n= 5.019, i= 2, Down: 5.01, Closest: 5.02
(注意:这是 1 位小数和 100.39
输入的不同输出。请说明在这种情况下 100.2
的所需输出?输出不应该是 100.3
?)
经过澄清,我认为您只需要使用 fmod
:
import math
def rnd(n,f,prec,direction='down'):
if direction=='down':
if prec==0:
return str(int(n))
return str(round(n-math.fmod(n,f),prec))
else:
if prec==0:
return str(int(round(n)))
n+=f
return str(round(n-math.fmod(n,f),prec))
适用于给定的所有示例:
>>> rnd(500.99,0.1,0)
'500'
>>> rnd(500.99,0.1,0,'')
'501'
>>> rnd(100.39,0.2,1,'')
'100.4'
>>> rnd(100.39,0.2,1)
'100.2'
>>> rnd(100.59,0.2,1,'')
'100.6'
>>> rnd(100.59,0.2,1)
'100.4'
>>> rnd(5.019,0.01,2)
'5.01'
>>> rnd(5.019,0.01,2,'')
'5.02'
(使用 direction=
关键字参数和除 'down'
以外的任何字符串值调用函数以起床。根据您的喜好更改...)
编辑 2
这个returns最接近输入数字的方法:
def rnd(n,f,prec):
n1=int(n) if prec==0 else round(n-math.fmod(n,f),prec)
n2=float(int(round(n))) if prec==0 else round((n+f)-math.fmod((n+f),f),prec)
return str(min((n1,n2), key=lambda e: math.fabs(e-n)))