Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert float number to string with engineering notation (with SI prefix) in Python

I have a float number such as x=23392342.1

I would like to convert it to a string with engineering notation (with metric prefix)

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

So in my example 23392342.1 = 23.3923421E6 = 23.3923421 M (mega)

I would like to display 23.3923421 M

like image 276
working4coins Avatar asked Mar 31 '13 19:03

working4coins


1 Answers

Here is a function inspired from 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'

    """

    inc_prefixes = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
    dec_prefixes = ['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(inc_prefixes):
                prefix = inc_prefixes[degree - 1]
            else:
                prefix = inc_prefixes[-1]
                degree = len(inc_prefixes)

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

        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()

and its usage:

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

It will display

23.3923421 M
like image 187
scls Avatar answered Oct 16 '22 08:10

scls