Con*_*ius 46 python string decimal
有没有一种简单的方法或集成函数来找出浮点数的小数位?
该数字是从字符串中解析出来的,因此一种方法是计算'.'后面的数字.标志,但这对我来说看起来很笨拙.是否有可能从一个float或一个Decimal对象中获取所需的信息?
解决方案(其中之一,当然:))
我选择使用python decimal.Decimal类来帮助解决我的问题:
e = abs(Decimal(string_value).as_tuple().exponent)
Run Code Online (Sandbox Code Playgroud)
注意:这仅适用于构造Decimal的参数是字符串而不是float(这会导致浮点不准确).
非常感谢所有其他贡献.
sen*_*rle 53
重复其他人所说的话(因为我已经输入了它!),我甚至不确定这个值在浮点数的情况下是否有意义,因为十进制和二进制表示之间的差异; 通常,由有限数量的十进制数字表示的数字将仅具有二进制的无限数字表示.
在的情况下,decimal.Decimal对象,你可以使用检索指数as_tuple方法,它返回一个namedtuple sign,digits和exponent属性:
>>> d = decimal.Decimal('56.4325')
>>> d.as_tuple().exponent
-4
>>> d = decimal.Decimal('56.43256436')
>>> d.as_tuple().exponent
-8
Run Code Online (Sandbox Code Playgroud)
除非指数大于,否则指数的否定是小数点后的位数0.
Mik*_*ton 12
一种天真的方式(易受@jglouie提到的本地化使用)是
len(foo.split('.')[1])
Run Code Online (Sandbox Code Playgroud)
其中foo是一个像"23.512999238"这样的字符串.
正如@Thomas Jung和@Mark Ransom所提到的,对于一些需要处理的角落情况来说这是相当幼稚的......
import re
from locale import localeconv
dec_pt = localeconv()['decimal_point']
decrgx = re.compile("\d+(%s\d+)?e(-|\+)(\d+)" % dec_pt)
if decrgx.search(foo):
# still figuring this out
raise NotImplementedError, "e notation not implemented"
else:
digits = len(foo.split(dec_pt)[-1])
Run Code Online (Sandbox Code Playgroud)
Ale*_*der 12
"小数位数"不是浮点数具有的属性,因为它们在内部存储和处理的方式.
您可以从浮点数中获取任意数量的小数位数.问题是你想要多少精确度.将浮点数转换为字符串时,部分过程决定了准确性.
试试例如:
1.1 - int(1.1)
Run Code Online (Sandbox Code Playgroud)
你会看到答案是:
0.10000000000000009
Run Code Online (Sandbox Code Playgroud)
因此,对于这种情况,小数位数是17.这可能不是您要查找的数字.
但是,您可以使用"round"将数字四舍五入到一定数量的小数:
round(3.1415 - int(3.1415), 3)
Run Code Online (Sandbox Code Playgroud)
对于这种情况,小数位数减少到3.
你不能得到"浮点数的小数",但你可以决定准确度和你想要的数量.
将浮点数转换为字符串是做出此类决定的一种方法.
小智 8
我发现小数点后计算数字并对数字进行四舍五入的最快方法是
计算数字:
a=decimal.Decimal('56.9554362669143476');
lenstr = len(str(a).split(".")[1])
Run Code Online (Sandbox Code Playgroud)
计算、检查和四舍五入:
a=decimal.Decimal('56.9554362669143476');
a = round(float(a),5) if len(str(a).split(".")[1]) > 5 else float(a)
Run Code Online (Sandbox Code Playgroud)
比较:
$ 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
Run Code Online (Sandbox Code Playgroud)
如果您只需要找到最高有效数字的小数位,即。最左边的,另一种原始解决方案是:
fraction = 0.001
decimal_places = int(f'{fraction:e}'.split('e')[-1])
Run Code Online (Sandbox Code Playgroud)
这利用了科学记数法 (mx 10^n),它已经以 10 的幂 (n) 的形式提供了小数位数,系数 (m) 增加到该幂,即:-3,从上述示例的 1.000000e-03 派生。
的一个重要区别Decimal(str(fraction)).as_tuple().exponent是,科学记数法始终只考虑指数 n 的最高有效数字,类似于Decimal().adjusted(),而Decimal().as_tuple().exponent返回最低有效数字的指数。
当然,将字符串格式化为科学记数法也只能处理浮点数而不处理字符串,因此任何浮点算术问题仍然存在。然而,对于许多用例来说,上述内容可能就足够了。
小智 6
我需要这样的东西,我测试了其中的一些,我发现最快的是:
str(number)[::-1].find('.')
Run Code Online (Sandbox Code Playgroud)
由于浮点问题,即使使用 Decimal(number),所有模数也给了我错误的结果(请注意,我需要在脚本中使用它来修复整个数据库的价格)
len(str(Decimal(str(number))) % Decimal(1))) - 2
Run Code Online (Sandbox Code Playgroud)
当我们有浮点数或类似的东西时,将字符串放入 Decimal 的需要是相当不安的。
这是我的“长凳”: https: //repl.it/FM8m/17