我需要向下舍入,它应该是小数点后两位 尝试以下,
a = 28.266
print round(a, 2)
28.27
但预期值仅为28.26。
答案 0 :(得分:8)
好像你需要floor
:
import math
math.floor(a * 100)/100.0
# 28.26
答案 1 :(得分:4)
似乎你想要截断,而不是四舍五入。
一种简单的方法是将地板划分//
和常规划分/
结合起来:
>>> a = 28.266
>>> a // 0.01 / 100
28.26
除了常规除法之外,您还可以乘以(如cmc中的评论中所述):
>>> a // 0.01 * 0.01
28.26
类似地,您可以创建一个函数来向下舍入到其他更多/更少的小数,但由于浮点数是不精确的数字,这可能会导致不准确。
def round_down(value, decimals):
factor = 1 / (10 ** decimals)
return (value // factor) * factor
print(round_down(28.266, 2))
# 28.26
但正如所说,它并不完全准确:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12.0
1 12.3
2 12.33
3 12.333
4 12.333300000000001 # weird, but almost correct
5 12.33332 # wrong
6 12.33333
7 12.33333
还有其他(更精确)的方法:
fraction
模块 fraction
s可以表示比float
更精确的十进制数。然后可以使用乘法,然后是地板,然后除以Psidom提到的方法,但具有更高的精度:
或作为功能:
import fractions
import math
a = 28.266
def round_down(value, decimals):
factor = 10 ** decimals
f = fractions.Fraction(value)
return fractions.Fraction(math.floor(f * factor), factor)
print(round_down(28.266, 2))
# 1413/50 <- that's 28.26
使用我用浮子做的测试:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12
1 123/10
2 1233/100
3 12333/1000
4 123333/10000
5 1233333/100000
6 1233333/100000
7 1233333/100000
但是,创建Fraction
不会神奇地修复不精确的float
,因此通常应该从字符串或分子 - 分母对而不是浮点数创建Fraction
。
decimal
模块您还可以使用decimal
模块,该模块提供各种舍入模式,包括向下舍入。
对于本演示,我使用上下文管理器来避免永久更改小数舍入模式:
import decimal
def round_down(value, decimals):
with decimal.localcontext() as ctx:
d = decimal.Decimal(value)
ctx.rounding = decimal.ROUND_DOWN
return round(d, decimals)
print(round_down(28.266, 2))
这为舍入提供了更明智的结果:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12
1 12.3
2 12.33
3 12.333
4 12.3333
5 12.33333
6 12.333330
7 12.3333300
与Fraction
一样,应该从字符串创建Decimal
以避免中间不精确的浮点数。但与Fraction
不同,Decimal
的精度有限,因此对于具有大量有效数字的值,它也会变得不精确。
然而,四舍五入只是可用选项之一。 available rounding modes的列表非常广泛:
舍入模式
decimal.ROUND_CEILING
向无限转。
decimal.ROUND_DOWN
向零回合。
decimal.ROUND_FLOOR
向无穷大方向前进。
decimal.ROUND_HALF_DOWN
四舍五入到最接近的关系为零。
decimal.ROUND_HALF_EVEN
舍入到最接近的关系到最近的偶数。
decimal.ROUND_HALF_UP
四舍五入到距离零最近的关系。
decimal.ROUND_UP
离开零点。
decimal.ROUND_05UP
如果舍入为零后的最后一位数字为0或5,则从零开始;否则往零。
答案 2 :(得分:3)
试试这个:
import math
a = 28.266
print((math.floor(a * 100)) / 100.0)
输出:
28.26
答案 3 :(得分:2)
这是一个不受浮点精度错误影响的简单函数
import psycopg2, sqlite3, sys
import time
import asyncio
sqdb="D://Python//SqliteToPostgreFull//testmydb6.db"
sqlike="table"
pgdb="testmydb9"
pguser="postgres"
pgpswd="1234"
pghost="127.0.0.1"
pgport="5432"
consq=sqlite3.connect(sqdb)
cursq=consq.cursor()
tabnames=[]
print()
cursq.execute('''SELECT name FROM sqlite_master WHERE type="table" AND name LIKE "'''+sqlike+'''%";''')
tabgrab = cursq.fetchall()
for item in tabgrab:
tabnames.append(item[0])
print(tabgrab)
async def copyTable(table):
cursq.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name = ?;", (table,))
create = cursq.fetchone()[0]
cursq.execute("SELECT * FROM %s;" %table)
rows=cursq.fetchall()
colcount=len(rows[0])
pholder='%s,'*colcount
newholder=pholder[:-1]
try:
conpg = psycopg2.connect(database=pgdb, user=pguser, password=pgpswd,
host=pghost, port=pgport)
curpg = conpg.cursor()
curpg.execute("DROP TABLE IF EXISTS %s;" %table)
create = create.replace("AUTOINCREMENT", "")
curpg.execute(create)
curpg.executemany("INSERT INTO %s VALUES (%s);" % (table, newholder),rows)
conpg.commit()
if conpg:
conpg.close()
except psycopg2.DatabaseError as e:
print ('Error %s' % e)
sys.exit(1)
finally:
print("Complete")
async def main():
for table in tabnames:
a = loop.create_task(copyTable(table,))
await asyncio.wait([a])
if __name__ == "__main__":
start_time = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
duration = time.time() - start_time
print(f"Duration {duration} seconds")
测试:
def truncate_float(n, places):
return int(n * (10 ** places)) / 10 ** places
答案 4 :(得分:1)
在Python 3.9中,您可以使用Quantize()
from decimal import *
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
我测试了以上答案,并成功了。但是我发现这1班轮很简单。所以我也在这里写下我的答案。
答案 5 :(得分:0)
一般来说,还有一种更简单的方法,就是在四舍五入之前减去少量,就像这样:
a = 28.269
digits = 2
print(round(a - 0.5/10**digits, digits))
这是基于这样的直觉:将浮点数四舍五入到最接近的整数的一种方法是先加上0.5,然后截断。上述解决方案则相反,其方法是减去所需精度允许的最小“刻度”的一半,然后四舍五入。