2015-08-21 65 views
2

(更新)Python:強制json中的浮點數的精度?

下面是我看到的實際問題。請注意,round()似乎並沒有成功。

這裏是我的代碼:

t0=time.time() 
# stuff 
t1=time.time() 
perfdat={'et1' : round(t1-t0,6), 'et2': '%.6f'%(t1-t0)} 

而且字典和JSON輸出,分別爲:

{'et2': '0.010214', 'et1': 0.010214000000000001} 

{"et2":"0.010214","et1":0.010214000000000001} 

(完更新)

我有一個浮點值有很多額外的精度數字,我不需要。格式化json字符串時,有沒有辦法截斷這些數字?

我可以得到我需要的截斷,如果我將該值格式化爲一個字符串,但我想傳遞該值作爲(截斷)數。

import json 
v=2.030000002 

json.dumps({'x':v})  # would like to just have 2.030 
'{"x": 2.030000002}' 

s= '%.3f' % (v)   # like this, but not as a string 
json.dumps({'x' : s}) 
'{"x": "2.030"}' 
+3

你需要尾隨0? –

+1

我無法想象爲什麼尾隨零將很重要。實際上,每個JSON庫都會將其解碼爲浮點值,這會丟失該信息。 –

+0

@ColonelThirtyTwo我同意,但另一方面,我也無法想象一個10萬用戶無法在谷歌或其他地方找到'round()'函數,因爲它之前已經詢問過這個話題 –

回答

2

這下面的方法很有前途:

import json 

v = 2.030000002 
result = [] 
for part in json.JSONEncoder().iterencode({'x': v}): 
    try: 
     tmp = round(float(part), 3) 
    except ValueError: 
     pass 
    else: 
     part = '{:.3f}'.format(tmp) 
    result.append(part) 
result = ''.join(result) 

print result # -> {"x": 2.030} 
1

內置函數round可以幫助

In [16]: v=2.030000002 

In [17]: json.dumps({'x': round(v, 3)}) 
Out[17]: '{"x": 2.03}' 
+0

尾部零缺失 –

+1

@TimCastelijns'2.03'與'2.030'的編號相同 – Alik

+0

是的,但是OP可能有不同的原因需要額外的0.無法想象一個10萬用戶找不到'round() '函數 –

2

包裹數量爲float

>>> s = float('%.3f' % (v)) 
>>> json.dumps({'x' : s}) 
{"x": 2.03} 
+0

爲我工作。在我的情況下,問題是數據在處理過程中轉換爲numpy的'float64'。明確地轉換'float'恢復原始格式 – Tim

1

這是我從發現從Python Standard library

「不同於硬件基於二進制浮點的de cimal模塊具有用戶可改變精度(默認爲28位),根據需要爲一個給定的問題,可以大有所爲:

>>> from decimal import * 
>>> getcontext().prec = 6 
>>> Decimal(1)/Decimal(7) 
Decimal('0.142857') 
>>> getcontext().prec = 28 
>>> Decimal(1)/Decimal(7) 
Decimal('0.1428571428571428571428571429') 

更好的import語句應該是:

from decimal import getcontext, Decimal 

然後,您可以應用這些相同的函數來指定任意精度。希望這可以幫助!我以前沒有真正使用過。

對於您的情況:(仍然有尾隨零問題)

getcontext().prec = 3 
s = '2.030' 
var = float(Decimal(s)) 

var回報2.03