有没有一种简单的方法或集成函数可以找出浮点数的小数位?
该数字是从字符串中解析出来的,所以一种方法是计算小数点后的数字个数,但这看起来相当笨拙。是否有可能从float
或Decimal
对象中获取所需的信息?
有没有一种简单的方法或集成函数可以找出浮点数的小数位?
该数字是从字符串中解析出来的,所以一种方法是计算小数点后的数字个数,但这看起来相当笨拙。是否有可能从float
或Decimal
对象中获取所需的信息?
重复之前其他人说过的话(因为我已经输入了它!),我甚至不确定在浮点数的情况下这样的值是否有意义,因为十进制和二进制表示之间的差异;通常一个可以由有限数量的十进制数字表示的数字,在二进制中只有无限位的表示。
对于 decimal.Decimal
对象,您可以使用 as_tuple
方法检索指数,该方法返回一个命名元组,其中包含 sign
、digits
和 exponent
属性:
>>> d = decimal.Decimal('56.4325')
>>> d.as_tuple().exponent
-4
>>> d = decimal.Decimal('56.43256436')
>>> d.as_tuple().exponent
-8
>>> d = decimal.Decimal(str(56.4325))
>>> d.as_tuple().exponent
-4
指数取反就是小数点后的位数,除非指数大于 0
。
decimal.Decimal("5e3").as_tuple().exponent
:5e3
的重要性小于5000
。 - tricasse由于浮点数的存储和内部处理方式,"小数位数"不是浮点数具有的属性。
您可以从浮点数中获取任意数量的小数位数。问题在于您需要多少精度。将浮点数转换为字符串时,部分过程是决定准确度。
例如,请尝试:
1.1 - int(1.1)
你会看到答案是:
0.10000000000000009
因此,对于这种情况,小数的位数为17。这可能不是你要找的数字。
但是,你可以使用“round”将数字四舍五入到一定数量的小数位数:
round(3.1415 - int(3.1415), 3)
在这种情况下,小数点后数字被缩减为3位。
你不能从浮点数中获取“小数点后数字的数量”,但你可以决定精度和想要的位数。
将浮点数转换为字符串是做出此类决策的一种方法。
fraction = 0.001
decimal_places = int(f'{fraction:e}'.split('e')[-1])
这里使用科学计数法 (m x 10^n),其中指数 (n) 表示了系数 (m) 被提高的 10 的次数,也就提供了数字的小数位数,例如上面例子中的 1.000000e-03 对应的指数为 -3。
与 Decimal(str(fraction)).as_tuple().exponent
的一个重要区别是,科学计数法始终只考虑最显著数字的指数 n,类似于 Decimal().adjusted()
,而 Decimal().as_tuple().exponent
返回的是最不显著数字的指数。
字符串格式化为科学计数法只能处理浮点数而不能处理字符串,因此任何浮点算术问题仍然存在。但对于许多用例来说,上述方法可能已经足够。
a=decimal.Decimal('56.9554362669143476');
lenstr = len(str(a).split(".")[1])
计算、校验和四舍五入:
a=decimal.Decimal('56.9554362669143476');
a = round(float(a),5) if len(str(a).split(".")[1]) > 5 else float(a)
比较:
$ python2 -mtimeit 'import decimal; a=decimal.Decimal('56.9554362669143476'); round(float(a),5) if a.as_tuple().exponent < -5 else float(a)'
10000 loops, best of 3: 32.4 usec per loop
$ python -mtimeit 'import decimal; a=decimal.Decimal('56.9554362669143476'); a = round(float(a),5) if len(str(a).split(".")[1]) > 5 else float(a)'
100000 loops, best of 3: 16.7 usec per loop
我需要类似于这样的东西,我测试了其中一些,最快速的是:
str(number)[::-1].find('.')
len(str(Decimal(str(number))) % Decimal(1))) - 2
当我们有浮点数或类似的内容时,需要将字符串转换为十进制相当困难。
这是我的“bench”: https://repl.it/FM8m/17
这将对您有所帮助 ;)
import decimal
def find_decimals(value):
return (abs(decimal.Decimal(str(value)).as_tuple().exponent))
# Floats
print (find_decimals(123.45678))
print (find_decimals(0.00001))
# Scientific Notation
print (find_decimals(1e-05))
# Strings
print (find_decimals('123.45678'))
print (find_decimals('0.00001'))
print (find_decimals('1e-05'))
输出:
5
5
5
5
5
5
最快的方法
precision = lambda x: len(str(x).split('.')[1])
显然要注意数据类型!
我需要这个,因为我需要动态地舍入一系列大大小小的数字。
>>> precision = lambda x: tuple(len(p) for p in str(x).split('.'))
>>> precision(123.345345)
(3, 6)
from math import log10
my_number = 3.1415927
int(log10(float(str(my_number)[::-1])))+1
它的工作原理是log10(number)+1将给出小数点左侧的数字数量。
如果我们反转数字,那么左侧的数字以前就在右侧。
# Reverse the string
any_string[::-1]
如果您知道不会出现解析问题(或者如果您让Python本身或其他库来处理这个问题,希望能够处理本地化问题)...只需解析它并使用modf。返回值是一对值,其中一个是整数部分,另一个是小数部分。
float
,无法得到小数位数。 - Constantinius