17

Using format strings in Python I can easily print a number in "scientific notation", e.g.

>> print '%g'%1e9
1e+09

What is the simplest way to format the number in LaTeX format, i.e. 1\times10^{+09}?

2
  • I don't think 1^{+09} is quite the output you want, but anyway. Commented Nov 21, 2012 at 10:31
  • True, of course I meant 10^{+09} Commented Nov 21, 2012 at 10:53

4 Answers 4

29

The siunitx LaTeX package solves this for you by allowing you to use the python float value directly without resorting to parsing the resulting string and turning it into valid LaTeX.

>>> print "\\num{{{0:.2g}}}".format(1e9)
\num{1e+09}

When the LaTeX document is compiled, the above code will be turned into enter image description here. As andybuckley points out in the comments, the plus sign might not be accepted by siunitx (I've not tested it), so it may be necessary to do a .repace("+", "") on the result.

If using siunitx is somehow off the table, write a custom function like this:

def latex_float(f):
    float_str = "{0:.2g}".format(f)
    if "e" in float_str:
        base, exponent = float_str.split("e")
        return r"{0} \times 10^{{{1}}}".format(base, int(exponent))
    else:
        return float_str

Testing:

>>> latex_float(1e9)
'1 \\times 10^{9}'
Sign up to request clarification or add additional context in comments.

7 Comments

Nice solution! This does what's asked for, however it's not normal to include a + sign or leading zero in the exponent when formatting for mathematical correctness (cf. the siunitx output above). Also, due to the \times command it's a good idea to use a raw ("r") string. These can be done by replacing the first return with: parts = float_str.split("e"); return r"{0} \times 10^{{{1}}}".format(parts[0], int(parts[1])) (Hope that's understandable: SO doesn't code-format in comments!)
@andybuckley Thanks for the feedback! I've corrected my answer.
I'm also not sure what input siunitx handles, just that its output is in the normal mathematical format without an explicit plus sign or leading 0 in the exponent. My bit of inline code in the comment above is (sadly) the most elegant way that I could think of to map a cast-to-int on the exponent... maybe there is something funky in itertools for such things but hopefully it's clear enough this way!
@andybuckley If we map both the exponent and the base to int (and there's no reason not to, as far as I know), we can make it more elegant. See above. :)
Erm, what happens to `latex_float(1.234e9) in that case? Or have I missed something obvious?! Obviously the mantissa-as-int works for the specific case of 1e9 :-)
|
8

Install num2tex:

pip install num2tex

and use it as so:

>>> from num2tex import num2tex
>>> '{:.0e}'.format(num2tex(1e9))
'1 \\times 10^{9}'

num2tex inherits from str so the format function can be used in the same way.

You can also change the format of the exponent by using num2tex.configure() (adding this in response to @Matt's comment).

>>>from num2tex import num2tex
>>>from num2tex import configure as num2tex_configure
>>>num2tex_configure(exp_format='cdot')
>>>num2tex(1.3489e17)
'1.3489 \cdot 10^{17}'
>>>num2tex_configure(exp_format='parentheses')
'1.3489 (10^{17})'

As of now this is undocumented in the GitHub, I'll try to change this soon!

Disclaimer: After using (and upvoting) Lauritz V. Thaulow's answer for a while (for Jupyter, Matplotlib etc.) I thought it would be better for my workflow to write a simple Python module, so I created num2tex on GitHub and registered it on PyPI. I would love to get some feedback on how to make it more useful.

4 Comments

The package you offer and the examples on GitHub page are infinitely useful! Cheers mate. :)
Would be nice if you found some times to implement the \cdot 10^{p} option. :)
@Matt it already has this feature, I just hadn't documented it :) See my edited answer for how to do it with cdot
I'm afraid there is a slight bug in the package. Quick example: num2tex(100000,precision=1) will yield $\times 10^5$, omitting the "1". it will happen for any $10^n$ with precision $\leq n+1$ (but not for $a.10^n$ if $a\neq 1$).
6

You can write a frexp10 function:

def frexp10(x):
    exp = int(math.floor(math.log10(abs(x))))
    return x / 10**exp, exp

Formatting in LaTeX style is then:

'{0}^{{{1:+03}}}'.format(*frexp10(-1.234e9))

Comments

1

I wrote a super simple python3 package called real2tex.

You can install it with pip:

pip install real2tex

And use it as follows:

from real2tex import real2tex

tex = real2tex(1.2345e-6, precision=2)
print(tex) # "1.23 \cdot 10^{\minus 6}"

If you are interested in the implementation, here I explain how it works. Firtst we have a function that takes a real number and returns a tuple representing it in scientific notation. It returns the mantissa, the exponent, and a boolean indicating if the exponent is negative. To do this, I exploit the built-in format specifier "{:.{precision}e}" that converts the number to a string representing it in scientific notation. The variable precision controls the number of decimal places in the mantissa (e.g., if precision=2, it will return something like "1.23e-6"). Once i have this string, I parse it to extract the mantissa, the exponent, and the sign of the exponent:

def scientific_notation(num: Real, precision: int = 2) -> tuple[str, str, bool]:
    num_str = f"{num:.{precision}e}"
    mantissa, exponent = num_str.split("e")
    negative_exponent = True if exponent[0] == "-" else False
    exponent = exponent[1:]
    # Remove leading zeros in the exponent
    exponent = exponent.lstrip("0")
    if len(exponent) == 0:
        exponent = "0"
    # Remove trailing zeros in the mantissa
    mantissa = mantissa.rstrip("0")
    # Remove trailing dot in the mantissa
    mantissa = mantissa.rstrip(".")
    # Remove sign if mantissa is zero
    if mantissa == "-0":
        mantissa = "0"
    return mantissa, exponent, negative_exponent

Once I have the mantissa, the exponent, and the sign of the exponent, it is easy to convert this information to LaTeX format:

def real2tex(
    num: Real, precision: int = 2, multiply_symbol: str = "\\cdot", no_10_to_the_zero: bool = True
) -> str:
    mantissa, exponent, negative_exponent = scientific_notation(num, precision)
    if negative_exponent:
        exponent = f"\\minus {exponent}"
    if exponent == "0" and no_10_to_the_zero:
        return f"{mantissa}"
    return f"{mantissa} {multiply_symbol} 10^{{{exponent}}}"

If you want to edit the code or report an issue, you can find it on GitHub.

2 Comments

Your answer could be improved with additional supporting information. How does your package work? Someone with the same question might not be able to install pip packages, or your package might become delisted in the future.
Hi @MatthewCole, I've added some supporting information about how the package works. Let me know if you spot something else that I can improve

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.