2013-03-31 24 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