244

Here's my code:

x = 1.0
y = 100000.0    
print x/y

My quotient displays as 1.00000e-05.

Is there any way to suppress scientific notation and make it display as 0.00001? I'm going to use the result as a string.

martineau
  • 119,623
  • 25
  • 170
  • 301
Matt
  • 3,356
  • 5
  • 21
  • 12
  • 35
    It is disappointing that none of the answers here address the question. It would be nice if there was a way to prevent python(3) from using scientific notation at all except when specified explicitly. All of the answers require the user to explicitly suppress scientific notation, which is not the same as generally suppressing the implicit use of scientific notation from within python. – BLUC Apr 27 '20 at 17:16
  • 8
    yes, like R does with `options(scipen = 999)` – Leonardo Siqueira Sep 21 '20 at 14:36
  • @BLUC the `numpy` module offers `np.format_float_positional()` and this works well. – D.L Dec 01 '22 at 15:25
  • Not worth an answer on it's own, but I believe https://stackoverflow.com/questions/67879685/python-decimal-decimal-producing-result-in-scientific-notation is better than any existing answer here if combined with `.replace(",", "")`. – Brendano257 Jan 24 '23 at 00:06
  • 1
    Python is so insane, I cannot stop being amazed by its intrinsic stupidity and lack of practicality comparing to literally any other modern language. Such a bummer this abomination became so popular. – Kirill Kay Mar 18 '23 at 10:40

16 Answers16

168

Using the newer version ''.format (also remember to specify how many digit after the . you wish to display, this depends on how small is the floating number). See this example:

>>> a = -7.1855143557448603e-17
>>> '{:f}'.format(a)
'-0.000000'

as shown above, default is 6 digits! This is not helpful for our case example, so instead we could use something like this:

>>> '{:.20f}'.format(a)
'-0.00000000000000007186'

Update

Starting in Python 3.6, this can be simplified with the new formatted string literal, as follows:

>>> f'{a:.20f}'
'-0.00000000000000007186'
Aziz Alto
  • 19,057
  • 5
  • 77
  • 60
80
'%f' % (x/y)

but you need to manage precision yourself. e.g.,

'%f' % (1/10**8)

will display zeros only.
details are in the docs

Or for Python 3 the equivalent old formatting or the newer style formatting

Chris
  • 6,331
  • 1
  • 21
  • 25
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
  • 10
    I suggest clarifying your statement to say, "you manage the *display* of precision yourself." The actual (Python internal) precision isn't changed, as is often done in other languages. – JS. Aug 22 '12 at 20:42
54

With newer versions of Python (2.6 and later), you can use ''.format() to accomplish what @SilentGhost suggested:

'{0:f}'.format(x/y)
nmichaels
  • 49,466
  • 12
  • 107
  • 135
54

Another option, if you are using pandas and would like to suppress scientific notation for all floats, is to adjust the pandas options.

import pandas as pd
pd.options.display.float_format = '{:.2f}'.format
JJAN
  • 777
  • 1
  • 7
  • 13
  • I found this answer useful specially combining it with the other answer [here](https://stackoverflow.com/a/70830393/5127304) for further endorsement: `import pandas as pd import numpy as np pd.options.display.float_format = '{:.2f}'.format np.set_printoptions(suppress=True)` – Elias Jun 19 '22 at 18:59
50

Most of the answers above require you to specify precision. But what if you want to display floats like this, with no unnecessary zeros:

1
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.000000000001

numpy has an answer: np.format_float_positional

import numpy as np

def format_float(num):
    return np.format_float_positional(num, trim='-')
Dennis Golomazov
  • 16,269
  • 5
  • 73
  • 81
  • 1
    this is **the best answer if you want a general number of decimal places** (ie. do not need to specify decimal places before). – D.L Dec 01 '22 at 16:03
14

In case of numpy arrays you can suppress with suppress command as

import numpy as np
np.set_printoptions(suppress=True)
joanis
  • 10,635
  • 14
  • 30
  • 40
Saran Zeb
  • 311
  • 3
  • 7
8

You can use the built-in format function.

>>> a = -3.42142141234123e-15
>>> format(a, 'f')
'-0.000000'
>>> format(a, '.50f') # Or you can specify precision
'-0.00000000000000342142141234122994048466990874926279'
qwerty_url
  • 535
  • 4
  • 12
  • 1
    Unfortunately this adds garbage numbers at the end of nice round floats like: `format(0.001, '.50f') = '0.00100000000000000002081668171172168513294309377670'` – SurpriseDog Apr 21 '23 at 23:55
6

This will work for any exponent:

def getExpandedScientificNotation(flt):
    str_vals = str(flt).split('e')
    coef = float(str_vals[0])
    exp = int(str_vals[1])
    return_val = ''
    if int(exp) > 0:
        return_val += str(coef).replace('.', '')
        return_val += ''.join(['0' for _ in range(0, abs(exp - len(str(coef).split('.')[1])))])
    elif int(exp) < 0:
        return_val += '0.'
        return_val += ''.join(['0' for _ in range(0, abs(exp) - 1)])
        return_val += str(coef).replace('.', '')
    return return_val
Captain Cucumber
  • 123
  • 1
  • 3
  • 9
4

This is using Captain Cucumber's answer, but with 2 additions.

1) allowing the function to get non scientific notation numbers and just return them as is (so you can throw a lot of input that some of the numbers are 0.00003123 vs 3.123e-05 and still have function work.

2) added support for negative numbers. (in original function, a negative number would end up like 0.0000-108904 from -1.08904e-05)

def getExpandedScientificNotation(flt):
    was_neg = False
    if not ("e" in flt):
        return flt
    if flt.startswith('-'):
        flt = flt[1:]
        was_neg = True 
    str_vals = str(flt).split('e')
    coef = float(str_vals[0])
    exp = int(str_vals[1])
    return_val = ''
    if int(exp) > 0:
        return_val += str(coef).replace('.', '')
        return_val += ''.join(['0' for _ in range(0, abs(exp - len(str(coef).split('.')[1])))])
    elif int(exp) < 0:
        return_val += '0.'
        return_val += ''.join(['0' for _ in range(0, abs(exp) - 1)])
        return_val += str(coef).replace('.', '')
    if was_neg:
        return_val='-'+return_val
    return return_val
FriskyGrub
  • 979
  • 3
  • 14
  • 25
Finn42
  • 49
  • 2
3

Since this is the top result on Google, I will post here after failing to find a solution for my problem. If you are looking to format the display value of a float object and have it remain a float - not a string, you can use this solution:

Create a new class that modifies the way that float values are displayed.

from builtins import float
class FormattedFloat(float):

    def __str__(self):
        return "{:.10f}".format(self).rstrip('0')

You can modify the precision yourself by changing the integer values in {:f}

Jared Marks
  • 948
  • 8
  • 15
2

If it is a string then use the built in float on it to do the conversion for instance: print( "%.5f" % float("1.43572e-03")) answer:0.00143572

U-571
  • 519
  • 2
  • 7
  • 23
2

In addition to SG's answer, you can also use the Decimal module:

from decimal import Decimal
x = str(Decimal(1) / Decimal(10000))

# x is a string '0.0001'
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Dana
  • 32,083
  • 17
  • 62
  • 73
1

A simpler solution to display a float to an arbitrary number of significant digits. No numpy or list comprehensions required here:

def sig(num, digits=3):
    "Return number formatted for significant digits"
    if num == 0:
        return 0
    negative = '-' if num < 0 else ''
    num = abs(float(num))
    power = math.log(num, 10)
    if num < 1:
        step = int(10**(-int(power) + digits) * num)
        return negative + '0.' + '0' * -int(power) + str(int(step)).rstrip('0')
    elif power < digits - 1:
        return negative + ('{0:.' + str(digits) + 'g}').format(num)
    else:
        return negative + str(int(num))

I'm stripping trailing 0s and displaying full integers in the example: sig(31415.9) = 31415 instead of 31400. Feel free to modify the code if that's not something you're into.

Testing:

for power in range(-8,8):
    num = math.pi * 10**power
    print(str(num).ljust(25), sig(num))
SurpriseDog
  • 462
  • 8
  • 18
0

Using 3.6.4, I was having a similar problem that randomly, a number in the output file would be formatted with scientific notation when using this:

fout.write('someFloats: {0:0.8},{1:0.8},{2:0.8}'.format(someFloat[0], someFloat[1], someFloat[2]))

All that I had to do to fix it was to add 'f':

fout.write('someFloats: {0:0.8f},{1:0.8f},{2:0.8f}'.format(someFloat[0], someFloat[1], someFloat[2]))
Scott Lohr
  • 74
  • 7
-1

As of 3.6 (probably works with slightly older 3.x as well), this is my solution:

import locale
locale.setlocale(locale.LC_ALL, '')

def number_format(n, dec_precision=4):
    precision = len(str(round(n))) + dec_precision
    return format(float(n), f'.{precision}n')

The purpose of the precision calculation is to ensure we have enough precision to keep out of scientific notation (default precision is still 6).

The dec_precision argument adds additional precision to use for decimal points. Since this makes use of the n format, no insignificant zeros will be added (unlike f formats). n also will take care of rendering already-round integers without a decimal.

n does require float input, thus the cast.

Alex S
  • 25,241
  • 18
  • 52
  • 63
-4

I was having a similar problem that randomly, using my solution:

from decimal import Decimal

Decimal(2/25500)
#output:0.00007843137254901961000728982664753630160703323781490325927734375
Mostafa
  • 5
  • 1
  • 2