我想用python打印一個工程格式的數字,但我似乎無法讓它工作。語法SEEMS很簡單,但它不起作用。工程格式的打印號碼
>>> import decimal
>>> x = decimal.Decimal(1000000)
>>> print x
1000000
>>>> print x.to_eng_string()
1000000
我想不通這是爲什麼。這兩個值不相等(一個是字符串,另一個是int)。在decimal
中設置各種上下文似乎也沒有幫助。任何線索或想法?
我想用python打印一個工程格式的數字,但我似乎無法讓它工作。語法SEEMS很簡單,但它不起作用。工程格式的打印號碼
>>> import decimal
>>> x = decimal.Decimal(1000000)
>>> print x
1000000
>>>> print x.to_eng_string()
1000000
我想不通這是爲什麼。這兩個值不相等(一個是字符串,另一個是int)。在decimal
中設置各種上下文似乎也沒有幫助。任何線索或想法?
爲了得到這個工作的編輯,你必須先規範十進制:
>>> x = decimal.Decimal ('10000000')
>>> x.normalize()
Decimal('1E+7')
>>> x.normalize().to_eng_string()
'10E+6'
其原因可以通過鑽研到源被發現碼。
如果檢查(從gzip壓縮的源焦油球hereLib/decimal.py
)在Python 2.7.3源代碼樹to_eng_string()
,它只是簡單地調用__str__
與eng
設置爲true。
然後你可以看到,它決定有多少數字去到小數點左邊最初:
leftdigits = self._exp + len(self._int)
下表顯示了該值是這兩件事情:
._exp ._int len leftdigits
----- --------- --- ----------
Decimal (1000000) 0 '1000000' 7 7
Decimal ('1E+6') 6 '1' 1 7
後一直延續的代碼是:
if self._exp <= 0 and leftdigits > -6:
# no exponent required
dotplace = leftdigits
elif not eng:
# usual scientific notation: 1 digit on left of the point
dotplace = 1
elif self._int == '0':
# engineering notation, zero
dotplace = (leftdigits + 1) % 3 - 1
else:
# engineering notation, nonzero
dotplace = (leftdigits - 1) % 3 + 1
,你可以看到,unle它已經在有指數在一定範圍內(self._exp > 0 or leftdigits <= -6
),在字符串表示中不會給它任何指數。
進一步的調查顯示了這種行爲的原因。查看代碼本身,您會發現它基於General Decimal Arithmetic Specification
(PDF here)。
的「以科學串」操作轉換:
如果你搜索
to-scientific-string
(上to-engineering-string
在很大程度上依賴)該文件,它在部分(轉述,並與我大膽位)規定一個數字到一個字符串,使用科學記數法如果需要指數。該操作不受上下文影響。如果該數量爲有限數,則:
使用字符0至9的係數首先被轉換爲一個字符串在基座10與無前導零(除非它的值是零,在這種情況下單個0字符被使用)。
接下來,計算調整後的指數;這是指數,加上轉換系數中的字符數,少一個。也就是說,指數+(clength-1),其中clength是係數的長度,以十進制數字表示。
如果指數小於或等於零,並且調整後的指數大於或等於-6,則該數字將被轉換爲不使用指數表示法的字符形式。在這種情況下,如果指數爲零,則不會添加小數點。否則(指數將爲負數),將插入一個小數點,指數的絕對值將指定小數點右側的字符數。根據需要將「0」字符添加到轉換系數的左側。如果在插入後沒有字符先於小數點,那麼傳統的「0」字符是前綴。
換句話說,它正在做它做的事情,因爲這是標準要求它做的事情。
爲什麼要麻煩檢查一下?我問了一些具體的問題。然後它決定我不想要那個,只想要我給它的東西?有時候Python會讓我困惑...... – jmurrayufo
@jmurrayufo,檢查更新。基本上,這是因爲這是標準要求它做的。 – paxdiablo
在我看來,你將不得不推出自己的:
from math import log10
def eng_str(x):
y = abs(x)
exponent = int(log10(y))
engr_exponent = exponent - exponent%3
z = y/10**engr_exponent
sign = '-' if x < 0 else ''
return sign+str(z)+'e'+str(engr_exponent)
雖然你可能要採取多一點關懷在z
部分的格式...
沒有很好的測試。隨意如果您發現錯誤
雖然我不介意的想法,我更好奇爲什麼'decimal'類並沒有做什麼,似乎它應該,或我怎麼用錯了 – jmurrayufo
@jmurrayufo - 對不起,我想我誤解了這個問題:)。 – mgilson
此前我試着回答,但發現它只是科學記數法。 未來版本的Python格式說明符(3.2?)將支持工程表示法,但不支持Python 2.7。
我意識到這是一個古老的線程,但它確實來了附近的一個python engineering notation
搜索的頂部。
我是一個喜歡「工程101」工程單位的工程師。我甚至不喜歡名稱如0.1uF
,我希望讀100nF
。我玩Decimal
類,並沒有真正喜歡它在可能值範圍內的行爲,所以我推出了一個名爲engineering_notation
的包,它可以通過pip安裝。
pip install engineering_notation
通過Python內:
>>> from engineering_notation import EngNumber
>>> EngNumber('1000000')
1M
>>> EngNumber(1000000)
1M
>>> EngNumber(1000000.0)
1M
>>> EngNumber('0.1u')
100n
>>> EngNumber('1000m')
1
此包還支持比較和其他簡單的數值的操作。
我發現這裏的解決方案「%0.4克」%× – lehalle