Czy istnieje pythonowy sposób dzielenia liczby, na przykład 1234.5678
na dwie części, (1234, 0.5678)
tj. Część całkowitą i część dziesiętną?
split
floating-point
python
Podwójne AA
źródło
źródło
int
jako nazwy zmiennej, spowoduje to przesłonięcieint
funkcji.int_
jeśli musisz mieć zmienną, która po przeczytaniu na głos nazywa się „int”.Możemy użyć niezbyt znanych funkcji wbudowanych; divmod:
>>> s = 1234.5678 >>> i, d = divmod(s, 1) >>> i 1234.0 >>> d 0.5678000000000338
źródło
divmod(-4.5,1)
daje -5,0 i 0,5. Użyciedivmod(-4.5, -1)
daje 4,0 i -0,5.>>> a = 147.234 >>> a % 1 0.23400000000000887 >>> a // 1 147.0 >>>
Jeśli chcesz, aby część całkowita była liczbą całkowitą, a nie liczbą zmiennoprzecinkową, użyj
int(a//1)
zamiast tego. Aby uzyskać krotkę w jednym fragmencie:(int(a//1), a%1)
EDYCJA: Pamiętaj, że część dziesiętna liczby zmiennoprzecinkowej jest przybliżona , więc jeśli chcesz przedstawić ją tak, jak zrobiłby to człowiek, musisz użyć biblioteki dziesiętnej
źródło
-2.25 // 1 == -3.0
i-2.25 % 1 == 0.75
. Może tego chciałby OP, ponieważ część int + część dziesiętna nadal jest równa wartości pierwotnej. Natomiastmath.modf(-2.25) == (-0.25, -2.0)
.Działa dla liczb dodatnich.
źródło
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
Ten wariant pozwala na uzyskanie pożądanej precyzji:
>>> 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)
źródło
U mnie to też działa
>>> val_int = int(a) >>> val_fract = a - val_int
źródło
Oto jak to robię:
num = 123.456 split_num = str(num).split('.') int_part = int(split_num[0]) decimal_part = int(split_num[1])
źródło
Jeśli nie masz nic przeciwko używaniu NumPy, to:
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)
źródło
Po zapoznaniu się z kilkoma odpowiedziami. Wymyśliłem te dwa stwierdzenia, które mogą dzielić liczby dodatnie i ujemne na części całkowite i ułamkowe bez uszczerbku dla dokładności. Test wydajności pokazuje, że dwie nowe instrukcje są szybsze
math.modf
, o ile nie są umieszczane w ich własnej funkcji lub metodzie.i = int(x) # i contains a positive or negative integer f = (x*1e17-i*1e17)/1e17 # f contains a positive or negative fraction
Np.
100.1323
->100, 0.1323
i-100.1323
->-100, -0.1323
Skrypt testowy:
#!/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()')
Wynik:
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}
UWAGA:
Instrukcja może być szybsza dzięki modulo, ale modulo nie może służyć do dzielenia liczb ujemnych na części całkowite i ułamkowe.
i, f = int(x), x*1e17%1e17/1e17 # x can not be negative
źródło