숫자를 정수 및 소수 부분으로 분할
다음과 같은 숫자를 나누는 비단조적인 방법이 있습니까?1234.5678
두 부분으로 나누어(1234, 0.5678)
즉, 정수 부분과 소수 부분?
사용:
import math
x = 1234.5678
math.modf(x) # (0.5678000000000338, 1234.0)
잘 알려지지 않은 내장 함수인 divmod를 사용할 수 있습니다.
>>> s = 1234.5678
>>> i, d = divmod(s, 1)
>>> i
1234.0
>>> d
0.5678000000000338
>>> a = 147.234
>>> a % 1
0.23400000000000887
>>> a // 1
147.0
>>>
정수 부분을 플로트가 아닌 정수로 사용하려면 다음을 사용합니다.int(a//1)
대신.단일 통로에서 튜플을 얻는 방법(int(a//1), a%1)
편집: 플로트 번호의 소수 부분은 근사하므로 사람이 표현하는 것처럼 표현하려면 소수 라이브러리를 사용해야 합니다.
intpart,decimalpart = int(value),value-int(value)
양수에 효과가 있습니다.
이 변형을 통해 원하는 정밀도를 얻을 수 있습니다.
>>> 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)
정확도(비트 오버플로)와 속도를 해치지 않고 양수와 음수를 정수와 분수로 나눌 수 있는 두 가지 문장을 생각해 냈습니다.
코드
# Divide a number (x) into integer and fraction
i = int(x) # Get integer
f = (x*1e17 - i*1e17) / 1e17 # Get fraction
값의 양의 값과 음의 값100.1323
다음과 같이 나뉩니다(100
,0.1323
) 및 (-100
,-0.1323
) 어디에서math.modf
결과는 (0.13230000000000075
,100.0
) 및 (-0.13230000000000075
,-100.0
).
속도 테스트
성능 테스트를 통해 두 문이 다음보다 빠름을 알 수 있습니다.math.modf
C/C++ 확장은 이를 개선합니다.
test.py
:
#!/usr/bin/env python
import math
import cProfile
""" Get the performance of both statements and math.modf """
X = -100.1323 # The number to be divided into integer and fraction
LOOPS = range(5 * 10 ** 6) # Number of loops
def scenario_a():
""" Get the performance of the statements """
for _ in LOOPS:
i = int(X) # -100
f = (X*1e17-i*1e17)/1e17 # -0.1323
def scenario_b():
""" Tests the speed of the statements when integer need to be 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 scenario_c():
""" Tests the speed of the statements in a function """
def modf(x):
i = int(x)
return i, (x*1e17-i*1e17)/1e17
for _ in LOOPS:
i, f = modf(X) # (-100, -0.1323)
def scenario_d():
""" Tests the speed of math.modf """
for _ in LOOPS:
f, i = math.modf(X) # (-0.13230000000000075, -100.0)
def scenario_e():
""" Tests the speed of math.modf when the integer part should be integer """
for _ in LOOPS:
f, i = math.modf(X) # (-0.13230000000000075, -100.0)
i = int(i) # -100
if __name__ == '__main__':
cProfile.run('scenario_a()')
cProfile.run('scenario_b()')
cProfile.run('scenario_c()')
cProfile.run('scenario_d()')
cProfile.run('scenario_e()')
결과:
4 function calls in 1.357 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.357 1.357 <string>:1(<module>)
1 1.357 1.357 1.357 1.357 test.py:11(scenario_a)
1 0.000 0.000 1.357 1.357 {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.858 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.858 1.858 <string>:1(<module>)
1 1.858 1.858 1.858 1.858 test.py:18(scenario_b)
1 0.000 0.000 1.858 1.858 {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.744 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.744 2.744 <string>:1(<module>)
1 1.245 1.245 2.744 2.744 test.py:26(scenario_c)
5000000 1.499 0.000 1.499 0.000 test.py:29(modf)
1 0.000 0.000 2.744 2.744 {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.904 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.904 1.904 <string>:1(<module>)
1 1.073 1.073 1.904 1.904 test.py:37(scenario_d)
1 0.000 0.000 1.904 1.904 {built-in method builtins.exec}
5000000 0.831 0.000 0.831 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.547 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.547 2.547 <string>:1(<module>)
1 1.696 1.696 2.547 2.547 test.py:43(scenario_e)
1 0.000 0.000 2.547 2.547 {built-in method builtins.exec}
5000000 0.851 0.000 0.851 0.000 {built-in method math.modf}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
C/C++ 확장
저는 C/C++ 지원으로 두 개의 진술서를 작성하려고 노력했고 결과는 더 좋았습니다.Python 확장 모듈을 사용하면 보다 빠르고 정확한 방법을 얻을 수 있었습니다.math.modf
.
math2.pyx
:
def modf(number):
cdef float num = <float> number
cdef int i = <int> num
return i, (num*1e17 - i*1e17) / 1e17
Cython의 기본 사항 참조
test.py
:
#!/usr/bin/env python
import math
import cProfile
import math2
""" Get the performance of both statements and math.modf """
X = -100.1323 # The number to be divided into integers and fractions
LOOPS = range(5 * 10 ** 6) # Number of loops
def scenario_a():
""" Tests the speed of the statements in a function using C/C++ support """
for _ in LOOPS:
i, f = math2.modf(X) # (-100, -0.1323)
def scenario_b():
""" Tests the speed of math.modf """
for _ in LOOPS:
f, i = math.modf(X) # (-0.13230000000000075, -100.0)
if __name__ == '__main__':
cProfile.run('scenario_a()')
cProfile.run('scenario_b()')
결과:
5000004 function calls in 1.629 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.629 1.629 <string>:1(<module>)
1 1.100 1.100 1.629 1.629 test.py:10(scenario_a)
1 0.000 0.000 1.629 1.629 {built-in method builtins.exec}
5000000 0.529 0.000 0.529 0.000 {math2.modf}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5000004 function calls in 1.802 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.802 1.802 <string>:1(<module>)
1 1.010 1.010 1.802 1.802 test.py:16(scenario_b)
1 0.000 0.000 1.802 1.802 {built-in method builtins.exec}
5000000 0.791 0.000 0.791 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 # Divide a number (x) into integer and fraction
값의 양의 값100.1323
다음과 같이 나뉩니다(100
,0.1323
) 그러면 음수 값이 잘못 나올 것입니다(-100
, 0.8677
).
제 방식은 이렇습니다.
num = 123.456
split_num = str(num).split('.')
int_part = int(split_num[0])
decimal_part = int(split_num[1])
이렇게 하면 (성스러운 음주자의 대답처럼) 선도 0을 떨어뜨리는 문제 없이 작업을 수행할 수 있습니다.
코드
def extract_int_decimal():
'''get the integer and decimal parts of a given number
by converting it to string and using split method
'''
num = 1234.5678
split_num = str(num).split('.')
int_part = int(split_num[0])
decimal_part = int(split_num[1]) * 10 ** -len(split_num[1])
print("integer part:",int_part)
print("decimal part:",decimal_part)
extract_int_decimal()
결과
integer part: 1234
decimal part: 0.5678000000000001
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)
언급URL : https://stackoverflow.com/questions/6681743/splitting-a-number-into-the-integer-and-decimal-parts
'UFO ET IT' 카테고리의 다른 글
Angular 응용 프로그램에서 라우팅으로 페이지 제목을 변경하는 방법은 무엇입니까? (0) | 2023.08.21 |
---|---|
Android - 스크롤 가능한 제약 조건 레이아웃을 만드는 방법은 무엇입니까? (0) | 2023.08.21 |
어떻게 파이썬 프로그램을 배포할 수 있습니까? (0) | 2023.08.21 |
@Qualifier와 @Resource의 차이 (0) | 2023.08.21 |
CSS 글꼴 속기에서 슬래시는 무엇을 의미합니까? (0) | 2023.08.21 |