Writing numbers in scientific notations

Introduction

We discuss a minor modification in the way numbers are written in the scientific notation with the goal to make them more readable, both for humans and computers.

Usually, numbers such as $134139349145$ are hard to parse. First, we count the digits to see how big the number is. Then, we try to make sense of the number by looking at the leading digit. If needed, we look at more digits to get a better sense of the number. This is a lot of work.

The scientific notation is a way to write numbers in a more readable format. For example, the number $134139349145$ can be written as $1.34139349145 \times 10^{11}$. This is much easier to parse. We can immediately see that the number is around $10^{11}$. In plaintext format, it can be written as 1.34139349145e11.

However, it is clear that the most significant information about the number is the exponent. Unfortunately, it appears at the end.

Proposal

  1. Write m(inus)/p(lus) depending on the sign of the number.
  2. Add ’e’ to indicate the exponent.
  3. Write m(inus)/p(lus) depending on the sign of the exponent.
  4. Write the exponent first in the fixed-width format (say 4).
  5. Add ‘b’ to indicate the base.
  6. Write the mantissa in the fixed-width format (say 4).

Alternatively, use “-"(ASCII 45 for minus)/” " (ASCII 160 for plus) rather than “m”/“p” to indicate the sign of the number/exponent.

Example:

134139349145
Scientific notation: 1.34139349145e11
New notation: pep  11b1.34

Advantages

  1. The most significant information about the number, the exponent, appears first.
  2. In a sense, more scientific since it resembles pH scale, Richter scale, etc.
  3. When compared to using Log of numbers, this notation also is useful for negative numbers.
  4. Number comparison is identical both numerically and alphabetically! , $a<b \iff str(a) < str(b)$

The last one is particularly useful in day to day life. Try sorting the following file by score.

id: 76,score: 2528926,wrong: 0
id: 10,score: 2576082,wrong: 0
id: 56,score: 25793,wrong: 21
id: 34,score: 2581965,wrong: 0
id: 79,score: 2615320,wrong: 0
id: 72,score: 2703,wrong: 31
id: 3,score: 2711668,wrong: 0
id: 24,score: 3,wrong: 62
id: 25,score: 3,wrong: 64

If we used the notation introduced here, the file would be sorted in vim easily.

:sort /score: /

In fact, vim can also do numerical comparison, without new notation,

:sort /score: \d*/ n r

Code

def convert_to_new_notation(number: float) -> str:
    """
    Convert a number to the new notation.

    >>> convert_to_new_notation(349412349)
    'pep0008b3.49'

    """
    if number == 0:
        return "pep0000b0.00"
    
    sign = "p" if number >= 0 else "m"
    number = abs(number)
    import math
    exponent = int(math.log10(number))
    exponent_sign= "p"
    if exponent < 0 :
        exponent -= 1
        exponent_sign = "m"
    exponent = abs(exponent)

    mantissa = 0.0
    if exponent_sign == 'p' :
        mantissa = number / (10 ** exponent)
    else:
        mantissa = number * (10 ** abs(exponent))
    return f"{sign}e{exponent_sign}{exponent:04d}b{mantissa:04.2f}"

def convert_from_new_notation(number: str) -> float:
    """
    Convert a number from the new notation.
    Note that the number only accurate upto 2 significant digits.

    >>> convert_from_new_notation('pep0008b3.49')
    349000000.0

    """
    sign = 1 if number[0] == 'p' else -1
    exponent_sign = 1 if number[2] == 'p' else -1
    exponent = int(number[3:7]) * exponent_sign
    mantissa = float(number[8:])
    return sign * mantissa * (10 ** exponent)


dict_test = {
    745: 'pep0002b7.45',
    -344: 'mep0002b3.44',
    364: 'pep0002b3.64',
    81: 'pep0001b8.10',
    -1000: 'mep0003b1.00',
    -805: 'mep0002b8.05',
    615: 'pep0002b6.15',
    -798: 'mep0002b7.98',
    749: 'pep0002b7.49',
    -907: 'mep0002b9.07',
    34345: 'pep0004b3.43',
    3434.5: 'pep0003b3.43',
    343.45: 'pep0002b3.43',
    34.345: 'pep0001b3.43',
    3.4345: 'pep0000b3.43',
    34345: 'pep0000b0.34',
    34345: 'pem0002b3.43',
    34345: 'pem0003b3.43'}

assert all(convert_to_new_notation(k) == v for k, v in dict_test.items())

Did you find this page helpful? Consider sharing it 🙌

Aaditya Salgarkar
Aaditya Salgarkar
PhD, Theoretical Physics

PhD in theoretical physics interested in programming, optimization and artificial intelligence.