Apakah ada cara pythonic untuk membagi bilangan 1234.5678
menjadi dua bagian (1234, 0.5678)
yaitu bilangan bulat dan bilangan desimal?
split
floating-point
python
AA ganda
sumber
sumber
int
sebagai nama variabel, itu akan menggantikanint
fungsi.int_
jika Anda harus memiliki variabel yang, ketika dibacakan, disebut "int".Kita bisa menggunakan fungsi built-in yang tidak terkenal; divmod:
>>> s = 1234.5678 >>> i, d = divmod(s, 1) >>> i 1234.0 >>> d 0.5678000000000338
sumber
divmod(-4.5,1)
memberikan -5.0 dan 0.5. Menggunakandivmod(-4.5, -1)
memberikan 4.0 dan -0.5.>>> a = 147.234 >>> a % 1 0.23400000000000887 >>> a // 1 147.0 >>>
Jika Anda ingin bagian integer sebagai integer dan bukan float, gunakan
int(a//1)
saja. Untuk mendapatkan tupel dalam satu bagian:(int(a//1), a%1)
EDIT: Ingatlah bahwa bagian desimal dari angka float adalah perkiraan , jadi jika Anda ingin merepresentasikannya seperti yang dilakukan manusia, Anda perlu menggunakan perpustakaan desimal
sumber
-2.25 // 1 == -3.0
dan-2.25 % 1 == 0.75
. Ini mungkin yang diinginkan OP, karena bagian int + bagian desimal masih sama dengan nilai aslinya. Sebaliknyamath.modf(-2.25) == (-0.25, -2.0)
,.Berfungsi untuk bilangan positif.
sumber
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
Varian ini memungkinkan mendapatkan presisi yang diinginkan:
>>> 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)
sumber
Ini juga berhasil untuk saya
>>> val_int = int(a) >>> val_fract = a - val_int
sumber
Inilah cara saya melakukannya:
num = 123.456 split_num = str(num).split('.') int_part = int(split_num[0]) decimal_part = int(split_num[1])
sumber
Jika Anda tidak keberatan menggunakan NumPy, maka:
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)
sumber
Setelah melihat beberapa jawaban. Saya telah menemukan dua pernyataan ini yang dapat membagi bilangan positif dan negatif menjadi bagian bilangan bulat dan pecahan tanpa mengorbankan akurasi. Pengujian kinerja menunjukkan bahwa dua pernyataan baru lebih cepat daripada
math.modf
, selama tidak dimasukkan ke dalam fungsi atau metode mereka sendiri.i = int(x) # i contains a positive or negative integer f = (x*1e17-i*1e17)/1e17 # f contains a positive or negative fraction
Misalnya
100.1323
->100, 0.1323
dan-100.1323
->-100, -0.1323
Skrip uji:
#!/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()')
Keluaran:
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}
CATATAN:
Pernyataan dapat lebih cepat dengan modulo, tetapi modulo tidak dapat digunakan untuk membagi bilangan negatif menjadi bilangan bulat dan pecahan.
i, f = int(x), x*1e17%1e17/1e17 # x can not be negative
sumber