我了解浮点计算由于其性质而不准确。我正在尝试找出进行多精度定量比较的最佳库/方法。我在比较分数、mpq 和 mpfr。后两个来自 gmpy2 库。第一个来自分数包。我正在使用python3.3
这是我用来比较的脚本。写的不是很好,很简单。
from fractions import Fraction
from gmpy2 import mpq, mpfr
import time
# This script compares gmpy2 library and Fraction library
total_pass_mpq = 0
total_pass_mpfr = 0
total_pass_frc = 0
a = mpq("-3.232429")
a_ = Fraction("-3.232429")
a__ = mpfr("-3.232429")
if str(float(a)) == "-3.232429":
total_pass_mpq +=1
if str(float(a_)) == "-3.232429":
total_pass_frc += 1
if str(float(a__)) == "-3.232429":
total_pass_mpfr += 1
b = mpq("604.08")
c = mpq("1.979")
b_ = Fraction("604.08")
c_ = Fraction("1.979")
b__ = mpfr("604.08")
c__ = mpfr("1.979")
if str(float(b*c)) == "1195.47432":
total_pass_mpq += 1
if str(float(b_*c_)) == "1195.47432":
total_pass_frc += 1
if str(float(b__*c__)) == "1195.47432":
total_pass_mpfr += 1
d = mpq(604.08)
e = mpq(1.979)
d_ = Fraction(604.08)
e_ = Fraction(1.979)
d__ = mpfr(604.08)
e__ = mpfr(1.979)
if str(float(d*e)) == "1195.47432":
total_pass_mpq += 1
if str(float(d_*e_)) == "1195.47432":
total_pass_frc += 1
if str(float(d__*e__)) == "1195.47432":
total_pass_mpfr += 1
f = mpq(-3.232429)
f_ = Fraction(-3.232429)
f__ = mpfr(-3.232429)
if str(float(f)) == "-3.232429":
total_pass_mpq +=1
if str(float(f_)) == "-3.232429":
total_pass_frc += 1
if str(float(f__)) == "-3.232429":
total_pass_mpfr +=1
g = mpq(503.79)
g_ = Fraction(503.79)
g__ = mpfr(503.79)
h = mpq(0.07)
h_ = Fraction(0.07)
h__ = mpfr(0.07)
if str(float(g*(1+h))) == "539.0553":
total_pass_mpq += 1
if str(float(g_*(1+h_))) == "539.0553":
total_pass_frc += 1
if str(float(g__*(1+h__))) == "539.0553":
total_pass_mpfr += 1
print("Total passed mpq: " + str(total_pass_mpq))
print("Total passed Fraction: " + str(total_pass_frc))
print("Total passed mpfr: " + str(total_pass_mpfr))
start_mpq = time.time()
for i in range(0, 50000):
y = mpq(0.32329)
z = mpq(-1)
yz = y*z
end_mpq = time.time()
print("Time for executing mpq: " + str(end_mpq - start_mpq))
start_frc = time.time()
for j in range(0, 50000):
y = Fraction(0.32329)
z = Fraction(-1)
yz_ = y*z
end_frc = time.time()
print("Time for executing frc: " + str(end_frc - start_frc))
start_frc_2 = time.time()
for j_ in range(0, 50000):
y = Fraction(0.32329)
z = Fraction(-1)
yz_2 = y*z
end_frc_2 = time.time()
print("Time for executing frc str: " + str(end_frc_2 - start_frc_2))
start_mpfr = time.time()
for k in range(0, 50000):
y = mpfr(0.32329)
z = mpfr(-1)
yz__ = y*z
end_mpfr = time.time()
print("Time for executing mpfr: " + str(end_mpfr - start_mpfr))
start_mpfr_2 = time.time()
for k_ in range(0, 50000):
y = mpfr("0.32329")
z = mpfr("-1")
yz__2 = y*z
end_mpfr_2 = time.time()
print("Time for executing mpfr str: " + str(end_mpfr_2 - start_mpfr_2))
这是结果:
Total passed mpq: 3
Total passed Fraction: 5
Total passed mpfr: 4
Time for executing mpq: 0.04700875282287598
Time for executing frc: 2.1327619552612305
Time for executing frc str: 2.0934295654296875
Time for executing mpfr: 0.05441713333129883
Time for executing mpfr str: 0.12844634056091309
所以基本上我得到的结果是分数是最准确的,但它非常慢。对于这个问题,我想问,
- 您认为我还应该尝试其他任何情况吗?
- 任何其他图书馆?
- 如果速度很重要,有没有办法使用 gmpy2 库来提高精度?