以可变精度打印浮点数
Print floating point numbers with variable precision
我想打印包含可变精度的浮点数。
我有多个号码,例如:
0.634564644534135499
0.0005462007746487777
0.028820785252590582
0.0018751147995774936
0.0075146048125540816
0.00046670455
我想得到与打印输出相同的数字。我知道可以使用 print("{:.19f}".format(0.0005462007746487777))
固定小数位数,但我不想固定小数位数。由于不同的数字会有不同的小数位
代码
#!/usr/bin/env python3
number_1=0.634564644534135499
number_2=0.0005462007746487777
number_3=0.028820785252590582
number_4=0.0018751147995774936
number_5=0.0075146048125540816
number_6=0.00046670455
print("Number 1: ",number_1)
print("Number 2: ",number_2)
print("Number 3: ",number_3)
print("Number 4: ",number_4)
print("Number 5: ",number_5)
print("Number 6: ",number_6)
实际输出:
Number 1: 0.6345646445341355
Number 2: 0.0005462007746487777
Number 3: 0.028820785252590582
Number 4: 0.0018751147995774936
Number 5: 0.0075146048125540816
Number 6: 0.00046670455
所需输出:
Number 1: 0.634564644534135499
Number 2: 0.0005462007746487777
Number 3: 0.028820785252590582
Number 4: 0.0018751147995774936
Number 5: 0.0075146048125540816
Number 6: 0.00046670455
我不明白的是为什么 2 号(具有更高的精度)打印正确,但 1 号 丢失了它精度?
从根本上说,float
对象不可能满足您的要求,这些对象基本上是 C-double 的包装器,因此是 64 位浮点数。
这里发生了几件事。在源代码中映射十进制文字输入存在根本问题:
0.634564644534135499
实际机器表示,不是十进制,而是二进制。
由于 64 位浮点格式的固有限制,多个十进制输入将映射到相同的底层表示形式:
>>> 0.634564644534135499 == 0.6345646445341355
True
实际上两者都不是,精确的小数实际上是:
>>> import decimal
>>> decimal.Decimal(0.6345646445341355)
Decimal('0.6345646445341355246227976749651134014129638671875')
>>> decimal.Decimal(0.634564644534135499)
Decimal('0.6345646445341355246227976749651134014129638671875')
当您天真地 print(some_float)
时, 实际打印的内容是 作为浮点十进制文字。事实上,since Python 3.1 CPython 使用 David Gray 的算法来寻找 最短 保留值的这种表示。
因此,由于 float
的固有限制而遇到麻烦时,通常会出现这种情况,请尝试使用 decimal.Decimal
。请记住,输入应该是 string。以下脚本:
import decimal
number_1 = decimal.Decimal('0.634564644534135499')
number_2 = decimal.Decimal('0.0005462007746487777')
number_3 = decimal.Decimal('0.028820785252590582')
number_4 = decimal.Decimal('0.0018751147995774936')
number_5 = decimal.Decimal('0.0075146048125540816')
number_6 = decimal.Decimal('0.00046670455')
print("Number 1: ",number_1)
print("Number 2: ",number_2)
print("Number 3: ",number_3)
print("Number 4: ",number_4)
print("Number 5: ",number_5)
print("Number 6: ",number_6)
打印:
Number 1: 0.634564644534135499
Number 2: 0.0005462007746487777
Number 3: 0.028820785252590582
Number 4: 0.0018751147995774936
Number 5: 0.0075146048125540816
Number 6: 0.00046670455
所以这里有一个数字的参考图片(从这个 link https://www.log2base2.com/number-system/float-to-binary-conversion.html 上取自网络):
Python用每一位存储整数部分和小数部分,用64位存储一个浮点数。因此,如果整数部分(绝对值)很高,则自动意味着小数部分将具有较少的存储位。
在你提供的例子中,由于每个值的整数部分都是0,所以完全可以在小数部分进行比较。
因此对于这种情况,我们将只查看小数部分中的值。
在第一个例子中(0.634564644534135499)虽然小数点后的数值比第二种情况(0.0005462007746487777)少,但第一种情况所需的位数比第二种情况多。因此存储的值将被四舍五入以确保位数符合 python.
中的要求
因此,要改变这一点,我能想到的一种方法是以字符串的形式将值存储在引号内。它会起作用,但假设您将从其他地方获取数据,不确定这是否非常好:
number_1="0.634564644534135499"
# number_3=0.028820785252590582
# number_4=0.0018751147995774936
# number_5=0.0075146048125540816
# number_6=0.00046670455
print("Number 1: ",number_1)
# print("Number 2: ",number_2)
另一种方法是使用 decimal.Decimal('0.634564644534135499')。如果我没有回答您的疑问,请告诉我为什么会这样,我会尽力解释得更好。
我想打印包含可变精度的浮点数。
我有多个号码,例如:
0.634564644534135499
0.0005462007746487777
0.028820785252590582
0.0018751147995774936
0.0075146048125540816
0.00046670455
我想得到与打印输出相同的数字。我知道可以使用 print("{:.19f}".format(0.0005462007746487777))
固定小数位数,但我不想固定小数位数。由于不同的数字会有不同的小数位
代码
#!/usr/bin/env python3
number_1=0.634564644534135499
number_2=0.0005462007746487777
number_3=0.028820785252590582
number_4=0.0018751147995774936
number_5=0.0075146048125540816
number_6=0.00046670455
print("Number 1: ",number_1)
print("Number 2: ",number_2)
print("Number 3: ",number_3)
print("Number 4: ",number_4)
print("Number 5: ",number_5)
print("Number 6: ",number_6)
实际输出:
Number 1: 0.6345646445341355
Number 2: 0.0005462007746487777
Number 3: 0.028820785252590582
Number 4: 0.0018751147995774936
Number 5: 0.0075146048125540816
Number 6: 0.00046670455
所需输出:
Number 1: 0.634564644534135499
Number 2: 0.0005462007746487777
Number 3: 0.028820785252590582
Number 4: 0.0018751147995774936
Number 5: 0.0075146048125540816
Number 6: 0.00046670455
我不明白的是为什么 2 号(具有更高的精度)打印正确,但 1 号 丢失了它精度?
从根本上说,float
对象不可能满足您的要求,这些对象基本上是 C-double 的包装器,因此是 64 位浮点数。
这里发生了几件事。在源代码中映射十进制文字输入存在根本问题:
0.634564644534135499
实际机器表示,不是十进制,而是二进制。
由于 64 位浮点格式的固有限制,多个十进制输入将映射到相同的底层表示形式:
>>> 0.634564644534135499 == 0.6345646445341355
True
实际上两者都不是,精确的小数实际上是:
>>> import decimal
>>> decimal.Decimal(0.6345646445341355)
Decimal('0.6345646445341355246227976749651134014129638671875')
>>> decimal.Decimal(0.634564644534135499)
Decimal('0.6345646445341355246227976749651134014129638671875')
当您天真地 print(some_float)
时, 实际打印的内容是 作为浮点十进制文字。事实上,since Python 3.1 CPython 使用 David Gray 的算法来寻找 最短 保留值的这种表示。
因此,由于 float
的固有限制而遇到麻烦时,通常会出现这种情况,请尝试使用 decimal.Decimal
。请记住,输入应该是 string。以下脚本:
import decimal
number_1 = decimal.Decimal('0.634564644534135499')
number_2 = decimal.Decimal('0.0005462007746487777')
number_3 = decimal.Decimal('0.028820785252590582')
number_4 = decimal.Decimal('0.0018751147995774936')
number_5 = decimal.Decimal('0.0075146048125540816')
number_6 = decimal.Decimal('0.00046670455')
print("Number 1: ",number_1)
print("Number 2: ",number_2)
print("Number 3: ",number_3)
print("Number 4: ",number_4)
print("Number 5: ",number_5)
print("Number 6: ",number_6)
打印:
Number 1: 0.634564644534135499
Number 2: 0.0005462007746487777
Number 3: 0.028820785252590582
Number 4: 0.0018751147995774936
Number 5: 0.0075146048125540816
Number 6: 0.00046670455
所以这里有一个数字的参考图片(从这个 link https://www.log2base2.com/number-system/float-to-binary-conversion.html 上取自网络):
Python用每一位存储整数部分和小数部分,用64位存储一个浮点数。因此,如果整数部分(绝对值)很高,则自动意味着小数部分将具有较少的存储位。
在你提供的例子中,由于每个值的整数部分都是0,所以完全可以在小数部分进行比较。
因此对于这种情况,我们将只查看小数部分中的值。
在第一个例子中(0.634564644534135499)虽然小数点后的数值比第二种情况(0.0005462007746487777)少,但第一种情况所需的位数比第二种情况多。因此存储的值将被四舍五入以确保位数符合 python.
中的要求因此,要改变这一点,我能想到的一种方法是以字符串的形式将值存储在引号内。它会起作用,但假设您将从其他地方获取数据,不确定这是否非常好:
number_1="0.634564644534135499"
# number_3=0.028820785252590582
# number_4=0.0018751147995774936
# number_5=0.0075146048125540816
# number_6=0.00046670455
print("Number 1: ",number_1)
# print("Number 2: ",number_2)
另一种方法是使用 decimal.Decimal('0.634564644534135499')。如果我没有回答您的疑问,请告诉我为什么会这样,我会尽力解释得更好。