181

How do I get the numbers after a decimal point?

For example, if I have 5.55, how do i get .55?

jpp
  • 159,742
  • 34
  • 281
  • 339
Alex Gordon
  • 57,446
  • 287
  • 670
  • 1,062
  • 2
    Related: [In Python how do I split a number by the decimal point?](http://stackoverflow.com/questions/3454085/in-python-how-do-i-split-a-number-by-the-decimal-point) – ire_and_curses Oct 07 '10 at 22:54
  • I think you should change the accepted answer on this. I almost didn't scroll down to the x10 times voted answer, and this would have bitten me later. – Gulzar Jun 17 '21 at 09:30
  • I think this is a simple approach: `float( '0.' + str(5.55).split('.')[1] )` >>> 0.55. But if someone thinks different, please let me know. – Abimael Domínguez Aug 12 '21 at 06:31

38 Answers38

278
5.55 % 1

Keep in mind this won't help you with floating point rounding problems. I.e., you may get:

0.550000000001

Or otherwise a little off the 0.55 you are expecting.

jer
  • 20,094
  • 5
  • 45
  • 69
  • 9
    As for `modf`, it can screw the precision as well: `math.modf(5.55)` will return (0.5499999999999998, 5.0). – bereal Mar 05 '12 at 05:31
  • 3
    does anyone know which would be the faster operation, this method described above, or: float b = a - int(a) ? i suspect the later, but wanted to see if there was confirmation – hokkuk Sep 08 '12 at 14:49
  • 9
    On a Raspberry Pi this method `x%1` was almost twice as fast as the `x-int(x)` and `modf(x)[0]` methods (the timings were 980ns, 1.39us, and 1.47us averaged over 1000000 runs). My value for `x` was always positive so I did not have to worry about that. – coderforlife Jan 06 '17 at 18:40
  • Definitely the module operation is faster. It doesn't have to do any name lookups. Whereas calling the int function does a lookup on the global variables. – Enrico Borba Sep 30 '17 at 08:28
  • fancy not just having a frac() – mckenzm Mar 09 '20 at 09:24
  • This works perfectly, but could anyone explain why it works? – Kyoujin Aug 09 '20 at 19:48
  • The % operator is the modulo operator, and rather than explain it in great detail here, I'll link an article instead. https://www.jquery-az.com/python-modulo/ – jer Aug 09 '20 at 23:02
  • 7
    Beware this breaks on negative numbers. – M. Lautaro Feb 17 '21 at 22:12
  • 1
    @M.Lautaro Just take the absolute value of the input before doing the modulus. It's a little slower, but still faster then using `math.modf` solution. – nightwuffle Dec 21 '22 at 23:59
  • `round(5.55 % 1,2)` – Hari Sharma Feb 16 '23 at 01:16
  • @eric .5 is a special case. With `-2.25 % 1` for example, the result is `0.75`. – wjandrea Mar 20 '23 at 16:14
  • 1
    @wjandrea yikes! Deleted my comment so as not to mislead people -- I use `math.modf()` solution now it gets it right in all cases. – eric Mar 20 '23 at 23:54
200

Use modf:

>>> import math
>>> frac, whole = math.modf(2.5)
>>> frac
0.5
>>> whole
2.0
Anthony V
  • 2,179
  • 1
  • 11
  • 6
  • 7
    Good solution, but, `math.modf(2.53) = (0.5299999999999998, 2.0)` expected answer is 0.53 – Lord Loh. Sep 24 '18 at 06:43
  • 14
    @LordLoh. that's because of floating point rounding, and will happen with any method. – Rena Jan 25 '19 at 20:55
  • 1
    @LordLoh. Try to use round(0.5299999999999998 , 2) to get 0.53 Another way is to use Decimal from decimal package. https://docs.python.org/2/library/decimal.html – SirJ May 07 '19 at 11:49
  • 3
    @Rena More precisely: "... and will happen for any method where the result has to be given as an IEEE 754 double-precision float." – Evgeni Sergeev May 17 '21 at 20:52
81

What about:

a = 1.3927278749291
b = a - int(a)

b
>> 0.39272787492910011

Or, using numpy:

import numpy
a = 1.3927278749291
b = a - numpy.fix(a)
Jim Brissom
  • 31,821
  • 4
  • 39
  • 33
43

Using the decimal module from the standard library, you can retain the original precision and avoid floating point rounding issues:

>>> from decimal import Decimal
>>> Decimal('4.20') % 1
Decimal('0.20')

As kindall notes in the comments, you'll have to convert native floats to strings first.

Community
  • 1
  • 1
intuited
  • 23,174
  • 7
  • 66
  • 88
  • For the benefit of the original question-asker: floats must be converted to a strings before they can be converted to Decimals. So if you have `n = 5.55`, n is a float, and you should do `Decimal(str(n)) % 1` to get the fractional part. (This isn't necessary if you have an integer, but it doesn't hurt.) – kindall Oct 07 '10 at 23:25
  • 2
    @intuited: It doesn't need to be decimal, it works also for float: `10.0/3 % 1` at least on my system – aherok Mar 29 '13 at 12:15
  • 3
    You can use from_float instead of using a string. d = Decimal.from_float(1.2) – Matthew Purdon Aug 15 '14 at 20:52
  • @intuited How does one obtain the decimal part as an integer? I have tried to_integer() methods but the type is still Decimal. – D1X Oct 26 '16 at 10:51
  • 4
    @MatthewPurdon - If you use `Decimal.from_float(1.2)` (which can now be written as `Decimal(1.2)`) you will have rounding issues, which this answer was trying to avoid. – John Y Jan 23 '20 at 16:14
30

An easy approach for you:

number_dec = str(number-int(number))[1:]
lllluuukke
  • 1,304
  • 2
  • 13
  • 17
  • 41
    Exercise for the reader: make it work for numbers larger than or equal to 10 – intuited Jan 06 '13 at 18:36
  • 1
    If you want to omit decimal point then simply do this `number_dec = str(n-int(n))[2:]` – Volatil3 Feb 27 '14 at 05:38
  • 11
    `number_dec = str(number-int(number)).split('.')[1]` – Ryan Allen Apr 11 '14 at 18:08
  • @intuited I was confused by your comment- this answer should work fine for numbers over 2 digits. You wont run into floating point issues until 2^14 (16384) for 2 decimal places, 2^13 (8192) for 3 decimal places, and so on. – Kyle Heuton Aug 07 '14 at 17:00
  • 43
    Downvote because this is an unnecessarily complicated approach. The answer I sought was the next answer, `5.55 % 1`, which is also a more generally useful answer--one can use the modulo division approach in multiple languages, whereas the above answer is Python-specific. – Stew Feb 03 '15 at 20:17
  • 3
    **NOTE:** This solution returns a string including the dot (``.55``), which you may not expect due the questions title! – T. Christiansen Mar 13 '15 at 08:18
  • @intuited still looking for that solution? any idea – garg10may Apr 27 '16 at 05:47
  • 3
    String based solutions are horrible if performance is important for your app. – Igor Soloydenko Jul 15 '16 at 09:49
  • @Anthony Vallone answer is cleaner and correct approach – Priyank Mehta May 26 '17 at 14:38
  • 16
    `str(5.55 - int(5.55))[1:]` returns `.5499999999999998` instead of the `.55` mentioned in the question. – Cristian Ciupitu Jul 17 '17 at 09:44
  • The shortest and correct answer is posted [here](https://stackoverflow.com/a/48463863/8928024). The solution posted here is regardless of float/int subtracting **"*number - number*"** and result in null or zeros or 0.0! – ZF007 Mar 03 '18 at 17:29
  • This is a real bad practice. Shouldn't be recommended as the accepted answer. – Pedro Alves Sep 11 '18 at 17:26
  • Another reason this is bad: I'm european, and here str will give 5,55 (we use comma). So the code is also needlessly restricted to american users. – Rasmus Damgaard Nielsen Jun 07 '20 at 12:26
  • Download because this is an unnecessarily complicated approach despite having simpler method. – khanh Mar 31 '21 at 03:28
10

Try Modulo:

5.55%1 = 0.54999999999999982
Juri Robl
  • 5,614
  • 2
  • 29
  • 46
10

To make it work with both positive and negative numbers: try abs(x)%1. For negative numbers, without with abs, it will go wrong.

5.55 % 1

output 0.5499999999999998

-5.55 % 1

output 0.4500000000000002

Albert G Lieu
  • 891
  • 8
  • 16
6
import math
orig = 5.55
whole = math.floor(orig)    # whole = 5.0
frac = orig - whole         # frac = 0.55
Kevin Lacquement
  • 5,057
  • 3
  • 25
  • 30
5

similar to the accepted answer, even easier approach using strings would be

def number_after_decimal(number1):
    number = str(number1)
    if 'e-' in number: # scientific notation
        number_dec = format(float(number), '.%df'%(len(number.split(".")[1].split("e-")[0])+int(number.split('e-')[1])))
    elif "." in number: # quick check if it is decimal
        number_dec = number.split(".")[1]
    return number_dec
Yonas Kassa
  • 3,362
  • 1
  • 18
  • 27
  • `number = 5.55; "." in number` gives `TypeError: argument of type 'float' is not iterable`. And what would you do if `number = 1e-5`? – Mark Dickinson Nov 19 '18 at 08:01
  • @mark the question is How do I get the numbers after a decimal point? so user is expecting float in decimal notation (not scientific notation), I've added a block for scientific notation too – Yonas Kassa Nov 19 '18 at 16:57
  • A number is a number; it's only _representations_ of a number that might be in scientific notation. So "float in decimal notation" doesn't make much sense here; by the time Python sees it, it's just a `float`; Python doesn't keep any knowledge of what format it was originally expressed in. My `number = 1e-5` example applies equally well to `number = 0.00001`: the `str` representation of the number is in scientific notation. You'll want to deal with `e+` as well as `e-`, by the way. – Mark Dickinson Nov 19 '18 at 17:06
4
>>> n=5.55
>>> if "." in str(n):
...     print "."+str(n).split(".")[-1]
...
.55
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • 3
    This is OK for garden-variety numbers, but doesn't work so well for numbers large (or small) enough to require scientific notation. – kindall Oct 08 '10 at 01:13
4

Just using simple operator division '/' and floor division '//' you can easily get the fraction part of any given float.

number = 5.55

result = (number/1) - (number//1)

print(result)
Sony
  • 55
  • 1
  • 5
3

Sometimes trailing zeros matter

In [4]: def split_float(x):
   ...:     '''split float into parts before and after the decimal'''
   ...:     before, after = str(x).split('.')
   ...:     return int(before), (int(after)*10 if len(after)==1 else int(after))
   ...: 
   ...: 

In [5]: split_float(105.10)
Out[5]: (105, 10)

In [6]: split_float(105.01)
Out[6]: (105, 1)

In [7]: split_float(105.12)
Out[7]: (105, 12)
George Fisher
  • 3,046
  • 2
  • 16
  • 15
3

Another example using modf

from math import modf
number = 1.0124584

# [0] decimal, [1] integer
result = modf(number)
print(result[0])
# output = 0124584
print(result[1])
# output = 1
camilom108
  • 51
  • 4
2

This is a solution I tried:

num = 45.7234
(whole, frac) = (int(num), int(str(num)[(len(str(int(num)))+1):]))
kurian
  • 171
  • 2
  • 10
2

Float numbers are not stored in decimal (base10) format. Have a read through the python documentation on this to satisfy yourself why. Therefore, to get a base10 representation from a float is not advisable.

Now there are tools which allow storage of numeric data in decimal format. Below is an example using the Decimal library.

from decimal import *

x = Decimal('0.341343214124443151466')
str(x)[-2:] == '66'  # True

y = 0.341343214124443151466
str(y)[-2:] == '66'  # False
jpp
  • 159,742
  • 34
  • 281
  • 339
2

Easier if the input is a string, we can use split()

decimal = input("Input decimal number: ") #123.456

# split 123.456 by dot = ['123', '456']
after_coma = decimal.split('.')[1] 

# because only index 1 is taken then '456'
print(after_coma) # '456'

if you want to make a number type print(int(after_coma)) # 456

kopidingin
  • 21
  • 1
1

Use floor and subtract the result from the original number:

>> import math #gives you floor.
>> t = 5.55 #Give a variable 5.55
>> x = math.floor(t) #floor returns t rounded down to 5..
>> z = t - x #z = 5.55 - 5 = 0.55
1

Example:

import math
x = 5.55
print((math.floor(x*100)%100))

This is will give you two numbers after the decimal point, 55 from that example. If you need one number you reduce by 10 the above calculations or increase depending on how many numbers you want after the decimal.

ilim
  • 4,477
  • 7
  • 27
  • 46
Frank
  • 19
  • 3
1
import math

x = 1245342664.6
print( (math.floor(x*1000)%1000) //100 )

It definitely worked

Blaztix
  • 1,223
  • 1
  • 19
  • 28
Ali
  • 11
  • 1
1

Another option would be to use the re module with re.findall or re.search:

import re


def get_decimcal(n: float) -> float:
    return float(re.search(r'\.\d+', str(n)).group(0))


def get_decimcal_2(n: float) -> float:
    return float(re.findall(r'\.\d+', str(n))[0])


def get_int(n: float) -> int:
    return int(n)


print(get_decimcal(5.55))
print(get_decimcal_2(5.55))
print(get_int(5.55))

Output

0.55
0.55
5

If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.


Source

How to get rid of additional floating numbers in python subtraction?

Emma
  • 27,428
  • 11
  • 44
  • 69
1

You can use this:

number = 5.55
int(str(number).split('.')[1])
1

This is only if you want toget the first decimal

print(int(float(input()) * 10) % 10)

Or you can try this

num = float(input())
b = num - int(num) 
c = b * 10
print(int(c))
magrinya
  • 11
  • 6
1

Using math module

speed of this has to be tested

from math import floor

def get_decimal(number):
    '''returns number - floor of number'''
    return number-floor(number)

Example:

n = 765.126357123

get_decimal(n)

0.12635712300004798

Jishnu P Das
  • 107
  • 4
  • Can test the speed with: ```from timeit import timeit iterations = 1000000 result = timeit( 'n = 765.126357123; x = n -floor(n)', 'from math import floor', number=iterations ) print("Total time was:", result) print("Time per iterations was:", result/iterations) ``` – run_the_race Nov 10 '20 at 07:18
1
def fractional_part(numerator, denominator):
    # Operate with numerator and denominator to 
# keep just the fractional part of the quotient
if  denominator == 0:
      return 0
  else:
       return (numerator/ denominator)-(numerator // denominator)  
 

print(fractional_part(5, 5)) # Should be 0
print(fractional_part(5, 4)) # Should be 0.25
print(fractional_part(5, 3)) # Should be 0.66...
print(fractional_part(5, 2)) # Should be 0.5
print(fractional_part(5, 0)) # Should be 0
print(fractional_part(0, 5)) # Should be 0
CruelFish
  • 11
  • 2
1
a = 12.587
b = float('0.' + str(a).split('.')[-1])
S.B
  • 13,077
  • 10
  • 22
  • 49
Ewin
  • 11
  • 1
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Ethan Jun 10 '22 at 01:21
0

What about:

a = 1.234
b = a - int(a)
length = len(str(a))

round(b, length-2)

Output:
print(b)
0.23399999999999999
round(b, length-2)
0.234

Since the round is sent to a the length of the string of decimals ('0.234'), we can just minus 2 to not count the '0.', and figure out the desired number of decimal points. This should work most times, unless you have lots of decimal places and the rounding error when calculating b interferes with the second parameter of round.

M H
  • 325
  • 3
  • 8
0

You may want to try this:

your_num = 5.55
n = len(str(int(your_num)))
float('0' + str(your_num)[n:])

It will return 0.55.

Ashkan Mirzaee
  • 300
  • 4
  • 14
0
number=5.55
decimal=(number-int(number))
decimal_1=round(decimal,2)
print(decimal)
print(decimal_1)

output: 0.55

Sanchit Aluna
  • 455
  • 2
  • 6
  • 20
0

See what I often do to obtain numbers after the decimal point in python 3:

a=1.22
dec=str(a).split('.')
dec= int(dec[1])
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

If you are using pandas:

df['decimals'] = df['original_number'].mod(1)
erickfis
  • 1,074
  • 13
  • 19
0

I've found that really large numbers with really large fractional parts can cause problems when using modulo 1 to get the fraction.

import decimal

>>> d = decimal.Context(decimal.MAX_PREC).create_decimal(
... '143000000000000000000000000000000000000000000000000000000000000000000000000000.1231200000000000000002013210000000'
... )
...
>>> d % 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.DivisionImpossible'>]

I instead grabbed the integral part and subtracted it first to help simplify the rest of it.

>>> d - d.to_integral()
Decimal('0.1231200000000000000002013210')
yurisich
  • 6,991
  • 7
  • 42
  • 63
0
def fractional_part(numerator, denominator):
    if denominator == 0:
        return 0
    else:
        return numerator / denominator - numerator // denominator

print(fractional_part(5, 5)) # Should be 0
print(fractional_part(5, 4)) # Should be 0.25
print(fractional_part(5, 3)) # Should be 0.66...
print(fractional_part(5, 2)) # Should be 0.5
print(fractional_part(5, 0)) # Should be 0
print(fractional_part(0, 5)) # Should be 0
Nutan Panta
  • 59
  • 1
  • 16
0

Late in the party, leaving comment for new visitors. If you know you need only 2 decimal places then you can use inbound round

round(1.15 % 1, 2)
0

I tried a lot of the other solutions but none of them work for me.

In my case, I have different operations and always in the last step, my result has more than the expected decimals.

For example, if you do:

61 * 0.1 the result is the float 6.1000000000000005

To get the 6.1 we have to parse the default float (at least in my case with 64bits) to a lower one:

import numpy as np    

x = 61 * 0.1
y = np.float32(x)

If you have a lot of operations before, try to do the casting at the end :)

To answer better the original questions it would be:

import math
import numpy as np    

x_deci, x_inte = math.modf(5.55)
decimals = np.float32(x_deci)

and the result for the decimals is 0.55 instead of 0.5499999999999998

Jon Ander
  • 740
  • 1
  • 14
  • 23
0

I was interested in the relative timing of the more sensible answers given here. Using this script on my laptop (MacBookPro16, 6-Core Intel Core i7 2.6 GHz):

#!/bin/sh

python3 -V
python3 -m timeit -s 'a = 5.55' 'b = a % 1'
python3 -m timeit -s 'a = 5.55' 'b = a - a//1'
python3 -m timeit -s 'a = 5.55; import math' 'b = a - math.floor(a)'
python3 -m timeit -s 'a = 5.55' 'b = a - int(a)'
python3 -m timeit -s 'a = 5.55; import math' 'frac, whole = math.modf(a)'

I get the following timing:

Python 3.9.10
10000000 loops, best of 5: 34.9 nsec per loop
5000000 loops,  best of 5: 51   nsec per loop
5000000 loops,  best of 5: 69.2 nsec per loop
5000000 loops,  best of 5: 84.1 nsec per loop
5000000 loops,  best of 5: 97.7 nsec per loop

So the simple % 1 seems the fastest approach

Chris
  • 852
  • 1
  • 8
  • 19
0

Try this def fuction

def decimales(n):
  n_int = int(n)
  n_int_len = len(int(str(n)))
  n_float = float(n)
  n_float_len = len(float(str(n)))
  n_decimal = n_float - n_int
  n_decimal_len = n_float_len - n_int_len
  n_decimal = round(n_decimal, n_decimal_len)
  return n_decimal

  
  • Answer needs supporting information Your answer could be improved with additional supporting information. Please [edit](https://stackoverflow.com/posts/76330061/edit) to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](https://stackoverflow.com/help/how-to-answer). – moken May 26 '23 at 12:14
-1

A solution is using modulo and rounding.

import math

num = math.fabs(float(5.55))
rem = num % 1

rnd_by =   len(str(num)) - len(str(int(num))) - 1

print(str(round(rem,rnd_by)))

Your output will be 0.55

-2

Another crazy solution is (without converting in a string):

number = 123.456
temp = 1

while (number*temp)%10 != 0:
    temp = temp *10
    print temp
    print number

temp = temp /10
number = number*temp
number_final = number%temp
print number_final
Romulus
  • 1,150
  • 3
  • 16
  • 26