将数字拆分为整数和小数部分

时间:2011-07-13 15:48:33

标签: split floating-point python

是否有一种pythonic方式将1234.5678之类的数字分成两部分(1234, 0.5678),即整数部分和小数部分?

9 个答案:

答案 0 :(得分:114)

使用math.modf

import math
x = 1234.5678
math.modf(x) # (0.5678000000000338, 1234.0)

答案 1 :(得分:53)

我们可以使用一个不着名的内置功能; divmod:

>>> s = 1234.5678
>>> i, d = divmod(s, 1)
>>> i
1234.0
>>> d
0.5678000000000338

答案 2 :(得分:32)

>>> a = 147.234
>>> a % 1
0.23400000000000887
>>> a // 1
147.0
>>>

如果您希望整数部分为整数而不是浮点数,请改用int(a//1)。要在单个段落中获取元组:(int(a//1), a%1)

编辑:请记住the decimal part of a float number is approximate,所以如果你想像人类一样代表它,你需要使用decimal library

答案 3 :(得分:13)

intpart,decimalpart = int(value),value-int(value)

适用于正数。

答案 4 :(得分:6)

此变体允许获得所需的精度:

>>> a = 1234.5678
>>> ( lambda x, y : ( int( x ), int( x * y ) % y / y ) )( a, 1e0 )
(1234, 0.0)
>>> ( lambda x, y : ( int( x ), int( x * y ) % y / y ) )( a, 1e1 )
(1234, 0.5)
>>> ( lambda x, y : ( int( x ), int( x * y ) % y / y ) )( a, 1e15 )
(1234, 0.5678)

答案 5 :(得分:3)

这对我也有用

>>> val_int = int(a)
>>> val_fract = a - val_int

答案 6 :(得分:1)

这就是我这样做的方式:

num = 123.456
split_num = str(num).split('.')
int_part = int(split_num[0])
decimal_part = int(split_num[1])

答案 7 :(得分:1)

如果你不介意使用NumPy,那么:

In [319]: real = np.array([1234.5678])

In [327]: integ, deci = int(np.floor(real)), np.asscalar(real % 1)

In [328]: integ, deci
Out[328]: (1234, 0.5678000000000338)

答案 8 :(得分:0)

看了几个答案之后。我想出了这两个语句,它们可以将正数和负数分为整数部分和小数部分,而不会影响精度(位溢出)。性能测试表明,只要不将这两个语句放入自己的函数或方法中,它们就会比math.modf快。

i = int(x) # i contains a positive or negative integer
f = (x*1e17-i*1e17)/1e17 # f contains a positive or negative fraction

例如100.1323-> 100, 0.1323-100.1323-> -100, -0.1323

测试脚本:

#!/usr/bin/env python
import math
import cProfile

""" Get the performance of both statements vs math.modf. """

X = -100.1323
LOOPS = range(5*10**6)

def fun_a():
    """ The integer part (i) is an integer, and
        the fraction part (f) is a float.
        NOTE: I think this is the most correct way. """
    for _ in LOOPS:
        i = int(X) # -100
        f = (X*1e17-i*1e17)/1e17 # -0.1323

def fun_b():
    """ The integer (i) and fraction (f) part will
        come out as float.
        NOTE: The only difference between this
              and math.modf is the accuracy. """
    for _ in LOOPS:
        i = int(X) # -100
        i, f = float(i), (X*1e17-i*1e17)/1e17 # (-100.0, -0.1323)

def fun_c():
    """ Performance test of the statements in a function.
        The integer part (i) is an integer, and
        the fraction part (f) is a float. """
    def modf(x):
        i = int(x)
        return i, (x*1e17-i*1e17)/1e17

    for _ in LOOPS:
        i, f = modf(X) # (-100, -0.1323)

def fun_d():
    for _ in LOOPS:
        f, i = math.modf(X) # (-100.0, -0.13230000000000075)

def fun_e():
    """ Convert the integer part to integer. """
    for _ in LOOPS:
        f, i = math.modf(X) # (-100.0, -0.13230000000000075)
        i = int(i) # -100

if __name__ == '__main__':
    cProfile.run('fun_a()')
    cProfile.run('fun_b()')
    cProfile.run('fun_c()')
    cProfile.run('fun_d()')
    cProfile.run('fun_e()')

输出:

         4 function calls in 1.312 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.312    1.312 <string>:1(<module>)
        1    1.312    1.312    1.312    1.312 new1.py:10(fun_a)
        1    0.000    0.000    1.312    1.312 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         4 function calls in 1.887 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.887    1.887 <string>:1(<module>)
        1    1.887    1.887    1.887    1.887 new1.py:17(fun_b)
        1    0.000    0.000    1.887    1.887 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         5000004 function calls in 2.797 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.797    2.797 <string>:1(<module>)
        1    1.261    1.261    2.797    2.797 new1.py:23(fun_c)
  5000000    1.536    0.000    1.536    0.000 new1.py:27(modf)
        1    0.000    0.000    2.797    2.797 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         5000004 function calls in 1.852 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.852    1.852 <string>:1(<module>)
        1    1.050    1.050    1.852    1.852 new1.py:34(fun_d)
        1    0.000    0.000    1.852    1.852 {built-in method builtins.exec}
  5000000    0.802    0.000    0.802    0.000 {built-in method math.modf}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         5000004 function calls in 2.467 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.467    2.467 <string>:1(<module>)
        1    1.652    1.652    2.467    2.467 new1.py:38(fun_e)
        1    0.000    0.000    2.467    2.467 {built-in method builtins.exec}
  5000000    0.815    0.000    0.815    0.000 {built-in method math.modf}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

注意:

使用模数语句可以更快,但是模数不能用于将负数拆分为整数和分数部分。

i, f = int(x), x*1e17%1e17/1e17 # x can not be negative