Có một cách thú vị để chia một số chẳng hạn như 1234.5678
thành hai phần (1234, 0.5678)
tức là phần nguyên và phần thập phân?
Câu trả lời:
Sử dụng math.modf
:
import math
x = 1234.5678
math.modf(x) # (0.5678000000000338, 1234.0)
int
làm tên biến, nó sẽ ghi đè lên int
hàm.
int_
nếu bạn phải có một biến mà khi đọc to, được gọi là "int".
Chúng ta có thể sử dụng một hàm tích hợp không nổi tiếng; divmod:
>>> s = 1234.5678
>>> i, d = divmod(s, 1)
>>> i
1234.0
>>> d
0.5678000000000338
divmod(-4.5,1)
cho -5,0 và 0,5. Sử dụng divmod(-4.5, -1)
cho kết quả là 4,0 và -0,5.
>>> a = 147.234
>>> a % 1
0.23400000000000887
>>> a // 1
147.0
>>>
Nếu bạn muốn phần nguyên là số nguyên chứ không phải số thực, hãy sử dụng int(a//1)
thay thế. Để lấy tuple trong một đoạn văn:(int(a//1), a%1)
CHỈNH SỬA: Hãy nhớ rằng phần thập phân của một số thực là gần đúng , vì vậy nếu bạn muốn biểu diễn nó như con người sẽ làm, bạn cần sử dụng thư viện thập phân
-2.25 // 1 == -3.0
và -2.25 % 1 == 0.75
. Đây có thể là những gì OP muốn, vì phần int + phần thập phân vẫn bằng giá trị ban đầu. Ngược lại math.modf(-2.25) == (-0.25, -2.0)
,.
intpart,decimalpart = int(value),value-int(value)
Hoạt động cho các số dương.
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
Đây là cách tôi làm điều đó:
num = 123.456
split_num = str(num).split('.')
int_part = int(split_num[0])
decimal_part = int(split_num[1])
Sau khi xem xét một số câu trả lời. Tôi đã nghĩ ra hai câu lệnh này có thể chia số dương và số âm thành các phần nguyên và phân số mà không ảnh hưởng đến độ chính xác. Kiểm tra hiệu suất cho thấy rằng hai câu lệnh mới nhanh hơn math.modf
, miễn là chúng không được đưa vào hàm hoặc phương thức của riêng chúng.
i = int(x) # i contains a positive or negative integer
f = (x*1e17-i*1e17)/1e17 # f contains a positive or negative fraction
Ví dụ 100.1323
-> 100, 0.1323
và -100.1323
->-100, -0.1323
Tập lệnh thử nghiệm:
#!/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()')
Đầu ra:
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}
GHI CHÚ:
Câu lệnh có thể nhanh hơn với modulo, nhưng modulo không thể được sử dụng để chia số âm thành phần nguyên và phần phân số.
i, f = int(x), x*1e17%1e17/1e17 # x can not be negative