Teilen einer Zahl in Ganzzahl und Dezimalzahl

91

Gibt es eine pythonische Möglichkeit, eine Zahl 1234.5678in zwei Teile aufzuteilen, (1234, 0.5678)dh den ganzzahligen Teil und den dezimalen Teil?

Doppelte AA
quelle

Antworten:

140

Verwendung math.modf:

import math
x = 1234.5678
math.modf(x) # (0.5678000000000338, 1234.0)
mhyfritz
quelle
2
Perfekt! Funktioniert auch hervorragend mit Negativen! Vielen Dank
Double AA
1
Nach dem Anwenden von math.modf (x) Wie kann ich mit Ergebniswerten umgehen? Wenn ich beispielsweise 1234.0 einer Variablen zuordne, wie kann ich das tun?
Hakiko
3
dec, int = math.modf (1234.5678)
gbtimmon
17
Nicht intals Variablenname verwenden, da dies die intFunktion überschreibt .
Holloway
2
@Trengot - Verwenden int_Sie diese Option, wenn Sie eine Variable benötigen , die beim Vorlesen "int" heißt.
ArtOfWarfare
59

Wir können eine nicht berühmte eingebaute Funktion verwenden; divmod:

>>> s = 1234.5678
>>> i, d = divmod(s, 1)
>>> i
1234.0
>>> d
0.5678000000000338
utdemir
quelle
4
Gibt möglicherweise nicht intuitive Ergebnisse für negative Zahlen: divmod(-4.5,1)ergibt -5,0 und 0,5. Die Verwendung divmod(-4.5, -1)ergibt 4.0 und -0.5.
Holloway
42
>>> a = 147.234
>>> a % 1
0.23400000000000887
>>> a // 1
147.0
>>>

Wenn Sie den Integer-Teil als Integer und nicht als Float verwenden möchten, verwenden Sie int(a//1)stattdessen. So erhalten Sie das Tupel in einer einzigen Passage:(int(a//1), a%1)

BEARBEITEN: Denken Sie daran, dass der Dezimalteil einer Gleitkommazahl ungefähr ist. Wenn Sie ihn also so darstellen möchten, wie es ein Mensch tun würde, müssen Sie die Dezimalbibliothek verwenden

Mac
quelle
4
Etwas verwirrende Ergebnisse für negative Zahlen -2.25 // 1 == -3.0und -2.25 % 1 == 0.75. Dies kann das sein, was das OP möchte, da int part + decimal part immer noch dem ursprünglichen Wert entspricht. Im Gegensatz dazu math.modf(-2.25) == (-0.25, -2.0).
Andrew Clark
@ Andrew - guter Punkt! Ich denke, die Antwort von @ mhyfritz ist sowieso besser!
Mac
Schön - ich denke, dies wäre der schnellste Weg der hier gezeigten unter Berücksichtigung von Andrew Clarks Vorbehalt für negative Zahlen
Jacanterbury
14
intpart,decimalpart = int(value),value-int(value)

Funktioniert für positive Zahlen.

Mark Ransom
quelle
In [1]: value = 1.89 In [2]: intpart,decimalpart = int(value),value-int(value) In [3]: intpart Out [3]: 1 In [4]: decimalpart Out [4]: 0.8899999999999999
iMom0
1
@ iMom0 - Siehe docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html und zahlreiche Fragen auf dieser Website zur Gleitkommagenauigkeit.
Mark Ransom
7

Diese Variante ermöglicht es, die gewünschte Präzision zu erzielen:

>>> 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)
dann
quelle
4

Das funktioniert auch bei mir

>>> val_int = int(a)
>>> val_fract = a - val_int
Shameem
quelle
0

So mache ich das:

num = 123.456
split_num = str(num).split('.')
int_part = int(split_num[0])
decimal_part = int(split_num[1])
Heiliger Trinker
quelle
4
Abhängig vom Anwendungsfall funktioniert dies wahrscheinlich nicht für Zahlen mit Null nach der Dezimalstelle (z. B. 123.0456)
Jon
Sie haben Recht: Es hängt vom Anwendungsfall ab. Wenn Sie es mit 123.0456 versuchen, ist das Ergebnis int_part = 123 und decimal_part = 456. In meinen Anwendungsfällen fand ich "die
Nullentfernung
0

Wenn es Ihnen nichts ausmacht, NumPy zu verwenden, dann:

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)
kmario23
quelle
0

Nachdem ich mir einige der Antworten angesehen habe. Ich habe mir diese beiden Aussagen ausgedacht, mit denen positive und negative Zahlen in Ganzzahl- und Bruchteile unterteilt werden können, ohne die Genauigkeit zu beeinträchtigen. Der Leistungstest zeigt, dass die beiden neuen Anweisungen schneller sind als math.modf, solange sie nicht in ihre eigene Funktion oder Methode eingefügt werden.

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

ZB 100.1323-> 100, 0.1323und -100.1323->-100, -0.1323

Testskript:

#!/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()')

Ausgabe:

         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}

HINWEIS:

Die Anweisung kann mit Modulo schneller sein, aber Modulo kann nicht verwendet werden, um negative Zahlen in Ganzzahl- und Bruchteile aufzuteilen.

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