2013-03-31 22 views
4

工程符號(與SI前綴)我有一個浮點數如x=23392342.1轉換浮點數到字符串可以用Python

我想將其轉換爲以工程符號的字符串(公制前綴)

http://en.wikipedia.org/wiki/Engineering_notation http://en.wikipedia.org/wiki/Metric_prefix

所以在我的例子23392342.1 = 23.3923421E6 = 23.3923421 M(兆)

我想顯示23.3923421 M

+0

除以1.0e6。 –

+0

請告訴我們你將如何解決你的問題,以及爲什麼你認爲你的想法不是最優的或者你想法的哪個部分不能實現。 – thejh

+0

我想我需要一個詞典來存儲每個公制前綴。我可能會計算log10來找到「3」倍數的「最接近」的指數(但除了da,h)...但這並不是那麼無足輕重......(因爲這個例外)......我也在想如果Python沒有STANDARD方式來實現這樣的任務,因爲我想管理每個可能的公制前綴 – working4coins

回答

8

下面是從Formatting a number with a metric prefix?

metric.py

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import math 


def to_si(d, sep=' '): 
    """ 
    Convert number to string with SI prefix 

    :Example: 

    >>> to_si(2500.0) 
    '2.5 k' 

    >>> to_si(2.3E6) 
    '2.3 M' 

    >>> to_si(2.3E-6) 
    '2.3 µ' 

    >>> to_si(-2500.0) 
    '-2.5 k' 

    >>> to_si(0) 
    '0' 

    """ 

    incPrefixes = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] 
    decPrefixes = ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'] 

    if d == 0: 
     return str(0) 

    degree = int(math.floor(math.log10(math.fabs(d))/3)) 

    prefix = '' 

    if degree != 0: 
     ds = degree/math.fabs(degree) 
     if ds == 1: 
      if degree - 1 < len(incPrefixes): 
       prefix = incPrefixes[degree - 1] 
      else: 
       prefix = incPrefixes[-1] 
       degree = len(incPrefixes) 

     elif ds == -1: 
      if -degree - 1 < len(decPrefixes): 
       prefix = decPrefixes[-degree - 1] 
      else: 
       prefix = decPrefixes[-1] 
       degree = -len(decPrefixes) 

     scaled = float(d * math.pow(1000, -degree)) 

     s = "{scaled}{sep}{prefix}".format(scaled=scaled, 
              sep=sep, 
              prefix=prefix) 

    else: 
     s = "{d}".format(d=d) 

    return(s) 


if __name__ == "__main__": 
    import doctest 
    doctest.testmod() 

及其使用啓發函數:

from metric import to_si 
d = 23392342.1 
print(to_si(d)) 

它將顯示

23.3923421 M 
+1

參數需要測試爲零爲[log10](https:/ /en.wikipedia.org/wiki/Logarithm)未定義,導致「ValueError:數學域錯誤」。例如。 : '''' 如果d == 0.0: 度= 0 否則: 度= INT(... '''' – handle

+1

我傾倒入一個擴展'int'類的'__str__'方法本所以它可用於字符串格式輸出。https://gist.github.com/thorsummoner/aed154cbba0cf9f61182示例:'import metric; print('>>%s'%metric。MetricInt(2 ** 16));' – ThorSummoner

5

直接的解決方案是使用Decimal.to_eng_string方法,然後執行字典查找將指數轉換爲適當的度量前綴。

+0

你如何得到指數值?你將不得不解析字符串! – working4coins

+0

有兩個相關的問題可以被認爲是重複的,應該被鏈接(自動?)。第一個使用你的解決方案(http://stackoverflow.com/questions/12311148/print-number-in-engineering-format)。重複也顯示了一種方法:http://stackoverflow.com/questions/12985438/print-numbers-in-terms-of-engineering-units-in-python – handle

1

使用QuantiPhy包。它是一個穩定的,有據可查的,支持良好的軟件包,旨在滿足您的需求。

>>> from quantiphy import Quantity 

>>> v = Quantity(23.3923421E6)            
>>> str(v)                 
'23.392M'                  

>>> v.render(prec='full')              
'23.3923421M' 

通常人們使用SI單位前綴與單位,Quantity設計用於將單位與數字組合。

>>> v = Quantity(23.3923421E6, 'V') 
>>> print(v) 
23.392 MV 

>>> f = Quantity('23.3923421 MHz') 
>>> print('{}'.format(f)) 
23.392 MHz 

數量的子類浮動,所以你可以象一個漂浮在表達式中使用量:

>>> t = 1/f                 
>>> print(t)                 
4.274903281275114e-08 

>>> t = Quantity(t, 's')              
>>> print(t) 
42.749 ns