在 Python 中截断为三位小数
- 2025-03-20 08:46:00
- admin 原创
- 42
问题描述:
我如何获得 1324343032.324?
正如您在下面看到的,以下操作不起作用:
>>1324343032.324325235 * 1000 / 1000
1324343032.3243253
>>int(1324343032.324325235 * 1000) / 1000.0
1324343032.3239999
>>round(int(1324343032.324325235 * 1000) / 1000.0,3)
1324343032.3239999
>>str(1324343032.3239999)
'1324343032.32'
解决方案 1:
float()
如果您想将其保留为,则可以在它周围使用附加项float
。
val = '%.3f'%(1324343032.324325235)
解决方案 2:
您可以使用以下函数将数字截断为一定数量的小数:
import math
def truncate(number, digits) -> float:
# Improve accuracy with floating point operations, to avoid truncate(16.4, 2) = 16.39 or truncate(-1.13, 2) = -1.12
nbDecimals = len(str(number).split('.')[1])
if nbDecimals <= digits:
return number
stepper = 10.0 ** digits
return math.trunc(stepper * number) / stepper
用法:
>>> truncate(1324343032.324325235, 3)
1324343032.324
解决方案 3:
我找到了另一个解决方案(它必须比“字符串巫术”解决方法更有效):
>>> import decimal
# By default rounding setting in python is decimal.ROUND_HALF_EVEN
>>> decimal.getcontext().rounding = decimal.ROUND_DOWN
>>> c = decimal.Decimal(34.1499123)
# By default it should return 34.15 due to '99' after '34.14'
>>> round(c,2)
Decimal('34.14')
>>> float(round(c,2))
34.14
>>> print(round(c,2))
34.14
关于小数模块
关于舍入设置
解决方案 4:
这个怎么样:
In [1]: '%.3f' % round(1324343032.324325235 * 1000 / 1000,3)
Out[1]: '1324343032.324'
Python 中的 round()可能重复,似乎没有正确舍入
[编辑]
鉴于我相信你会想做的补充评论:
In : Decimal('%.3f' % (1324343032.324325235 * 1000 / 1000))
Out: Decimal('1324343032.324')
浮点精度不会是您想要的:
In : 3.324
Out: 3.3239999999999998
(所有示例均使用 Python 2.6.5)
解决方案 5:
'%.3f'%(1324343032.324325235)
只是在这种特殊情况下才可以。
只需稍微改变一下数字:
1324343032.324 7 25235
进而:
'%.3f'%(1324343032.324725235)
为您提供1324343032.325
尝试一下这个:
def trun_n_d(n,d):
s=repr(n).split('.')
if (len(s)==1):
return int(s[0])
return float(s[0]+'.'+s[1][:d])
trun_n_d的另一个选项:
def trun_n_d(n,d):
dp = repr(n).find('.') #dot position
if dp == -1:
return int(n)
return float(repr(n)[:dp+d+1])
trun_n_d的另一个选项(一行代码)[假设' n ' 是str而 ' d ' 是int ]:
def trun_n_d(n,d):
return ( n if not n.find('.')+1 else n[:n.find('.')+d+1] )
trun_n_d在 Python 2.7 和 Python 3.6 中都提供所需的输出
trun_n_d(1324343032.324325235,3)返回1324343032.324
同样,trun_n_d(1324343032.324 7 25235,3)返回1324343032.324
注 1在 Python 3.6(可能还有 Python 3.x)中,下面的代码可以正常工作:
def trun_n_d(n,d):
return int(n*10**d)/10**d
但这样一来,圆形幽灵就会一直潜伏在周围。
注 2在这种情况下,由于python的数字内部结构(例如四舍五入和缺乏精度),使用str形式的n要比使用其int对应项好得多;您总是可以在最后将您的数字转换为浮点数。
解决方案 6:
使用 decimal 模块。但是如果你必须使用浮点数,并且仍然以某种方式将它们强制转换为给定数量的小数点,那么转换为字符串并返回提供了一种(恐怕相当笨拙的)方法。
>>> q = 1324343032.324325235 * 1000 / 1000
>>> a = "%.3f" % q
>>> a
'1324343032.324'
>>> b = float(a)
>>> b
1324343032.324
所以:
float("%3.f" % q)
解决方案 7:
我认为使用该format
函数是个坏主意。请参见下文。它会对值进行舍入。我使用的是 Python 3.6。
>>> '%.3f'%(1.9999999)
'2.000'
使用正则表达式来代替:
>>> re.match(r'd+.d{3}', str(1.999999)).group(0)
'1.999'
解决方案 8:
功能
def truncate(number: float, digits: int) -> float:
pow10 = 10 ** digits
return number * pow10 // 1 / pow10
测试代码
f1 = 1.2666666
f2 = truncate(f1, 3)
print(f1, f2)
输出
1.2666666 1.266
解释
f1
它将数字digits
向左移动几次,然后截掉所有小数,最后将数字digits
向右移动几次。
序列中的示例:
1.2666666 # number
1266.6666 # number * pow10
1266.0 # number * pow10 // 1
1.266 # number * pow10 // 1 / pow10
解决方案 9:
我建议下一个解决方案:
def my_floor(num, precision):
return f'{num:.{precision+1}f}'[:-1]
my_floor(1.026456,2) # 1.02
解决方案 10:
或许是这样的:
def myTrunc(theNumber, theDigits):
myDigits = 10 ** theDigits
return (int(theNumber * myDigits) / myDigits)
解决方案 11:
我认为最好和最合适的方法是使用decimal
模块。
import decimal
a = 1324343032.324325235
decimal_val = decimal.Decimal(str(a)).quantize(
decimal.Decimal('.001'),
rounding=decimal.ROUND_DOWN
)
float_val = float(decimal_val)
print(decimal_val)
>>>1324343032.324
print(float_val)
>>>1324343032.324
您可以使用不同的值rounding=decimal.ROUND_DOWN
,可用选项有、、、、、、、ROUND_CEILING
和。您可以在此处的文档中找到每个选项的解释。ROUND_DOWN
`ROUND_FLOORROUND_HALF_DOWN
ROUND_HALF_EVENROUND_HALF_UP
ROUND_UP`ROUND_05UP
解决方案 12:
Almo 的链接解释了为什么会发生这种情况。要解决此问题,请使用十进制库。
解决方案 13:
好吧,这只是解决这个问题的另一种方法,将数字作为字符串处理并对其进行简单的切片。这会为您提供截断的数字输出,而不是四舍五入的数字。
num = str(1324343032.324325235)
i = num.index(".")
truncated = num[:i + 4]
print(truncated)
输出:
'1324343032.324'
当然你可以解析:
float(truncated)
解决方案 14:
在寻找解决这个问题的方法后,无需加载任何 Python 3 模块或额外的数学运算,我仅使用 str.format() 和 .float() 解决了这个问题。我认为这种方法比使用其他数学运算(例如最常见的解决方案)更快。我需要一个快速的解决方案,因为我要处理非常大的数据集,因此它在这里运行得很好。
def truncate_number(f_number, n_decimals):
strFormNum = "{0:." + str(n_decimals+5) + "f}"
trunc_num = float(strFormNum.format(f_number)[:-5])
return(trunc_num)
# Testing the 'trunc_num()' function
test_num = 1150/252
[(idx, truncate_number(test_num, idx)) for idx in range(0, 20)]
它返回以下输出:
[(0, 4.0),
(1, 4.5),
(2, 4.56),
(3, 4.563),
(4, 4.5634),
(5, 4.56349),
(6, 4.563492),
(7, 4.563492),
(8, 4.56349206),
(9, 4.563492063),
(10, 4.5634920634),
(11, 4.56349206349),
(12, 4.563492063492),
(13, 4.563492063492),
(14, 4.56349206349206),
(15, 4.563492063492063),
(16, 4.563492063492063),
(17, 4.563492063492063),
(18, 4.563492063492063),
(19, 4.563492063492063)]
解决方案 15:
基于@solveMe 的答案(https://stackoverflow.com/a/39165933/641263),我认为这是利用十进制上下文最正确的方法之一,我创建了以下方法,它可以完全按照需要完成工作:
import decimal
def truncate_decimal(dec: Decimal, digits: int) -> decimal.Decimal:
round_down_ctx = decimal.getcontext()
round_down_ctx.rounding = decimal.ROUND_DOWN
new_dec = round_down_ctx.create_decimal(dec)
return round(new_dec, digits)
解决方案 16:
您还可以使用:
import math
nValeur = format(float(input('Quelle valeur ? ')), '.3f')
在 Python 3.6 中它可以工作。
解决方案 17:
a = 1.0123456789
dec = 3 # keep this many decimals
p = 10 # raise 10 to this power
a * 10 ** p // 10 ** (p - dec) / 10 ** dec
>>> 1.012
解决方案 18:
也许自从这个问题以来,python 发生了变化,下面的所有内容似乎都运行良好
Python2.7
int(1324343032.324325235 * 1000) / 1000.0
float(int(1324343032.324325235 * 1000)) / 1000
round(int(1324343032.324325235 * 1000) / 1000.0,3)
# result for all of the above is 1324343032.324
解决方案 19:
>>> float(1324343032.324325235) * float(1000) / float(1000)
1324343032.3243253
>>> round(float(1324343032.324325235) * float(1000) / float(1000), 3)
1324343032.324
解决方案 20:
我正在尝试生成一个 5 到 7 之间的随机数,并想将其限制为小数点后 3 位。
import random
num = float('%.3f' % random.uniform(5, 7))
print (num)
解决方案 21:
我开发了一个很好的解决方案,我知道有很多If
语句,但它有效!(它仅适用于<1 个数字)
def truncate(number, digits) -> float:
startCounting = False
if number < 1:
number_str = str('{:.20f}'.format(number))
resp = ''
count_digits = 0
for i in range(0, len(number_str)):
if number_str[i] != '0' and number_str[i] != '.' and number_str[i] != ',':
startCounting = True
if startCounting:
count_digits = count_digits + 1
resp = resp + number_str[i]
if count_digits == digits:
break
return resp
else:
return number
扫码咨询,免费领取项目管理大礼包!