float 연산자 코드
#float연산자
import sys
import stdio
a = float(sys.argv[1])
b = float(sys.argv[1])
total = a + b
diff = a - b
prod = a * b
quot = a / b
exp = a ** b
stdio.writeln(str(a) + ' + ' + str(b) + ' = ' + str(total))
stdio.writeln(str(a) + ' - ' + str(b) + ' = ' + str(diff))
stdio.writeln(str(a) + ' * ' + str(b) + ' = ' + str(prod))
stdio.writeln(str(a) + ' / ' + str(b) + ' = ' + str(quot))
stdio.writeln(str(a) + ' ** ' + str(b) + ' = ' + str(exp))
명령 프롬프트 실행 결과
정상적으로 작동한다.
실수를 사용하다 보면 가장 먼저 마주치는 문제 중 하나가 정밀도 문제다. 5.0/2.0은 2.5가 되지만 5.0/3.0은 1.6666666666666667로 평가된다. 일반적으로 실수는 소수점 15자리 내지 17자리 정도의 정밀도를 가진다. 추후 이 책의 1.5절에서는 실수를 출력할 때 표현할 소수점 이하 자릿수를 조정하는 방법을 설명한다.
float 객체를 이용해 계산할 때는 고려해야 할 사항이 아주 많지만, 모든 계산에 정밀 계산용 라이브러리를 사용할 필요 없이 float 객체를 사용해 자연스럽게 파이썬 프로그램을 작성할 수 있다. 예를 들어 quadratic.py(프로그램)는 계산에 float 객체를 사용해 이차 방정식 근 두 개를 구한다.
## 이차 방정식 근의 공식
import math
import sys
import stdio
b = float(sys.argv[1])
c = float(sys.argv[2])
discriminant = b*b - 4.0*c
d = math.sqrt(discriminant)
stdio.writeln((-b + d) / 2.0)
stdio.writeln((-b - d) / 2.0)
이 프로그램은 이차 방정식 근의 공식을 이용해 x²+bx + c 의 근을 구해 출력한다. 예를 들어 x²-3x + 2의 근을 구한다면
아래 처럼 구해지게 된다. 단 여기서 math 모듈의 sqrt 함수는 변수로 양수만 받게 되고 음수가 오면 오류 메시지가 출력된다.
math domain error라고 나오는 것을 볼 수 있다. 또한 -1.0 -1.0을 했을 때는 아래처럼 나온다 여기서 파이썬의 float연산자는 기본적으로 소수점 16자리까지 나타냄을 알 수 있다. 보통 일반 프로그램들은 15~17자리라고 한다.
2가지 인수를 받아서 정수형 객체로 a와 b에 바인딩 한다고 해보자 그리고 이를 이용해 math모듈의 sqrt 함수로 제곱근을 구해보자
import sys
import stdio
import math
a = int(sys.argv[1])
b = int(sys.argv[2])
result = math.sqrt(a)
print(result))
result = math.sqrt(b)
print(result)
실행해보니 결과가 잘 나오는데 2.0, 3.0 이런 식으로 표현되어 있는 것을 보니 입력이 정수형 객체라도 math.sqrt() 함수는 float 형 객체로 변환해서 출력하는 것으로 보인다. 만약 정수형으로 출력하고 싶다면 print함수 안에 result를 한 번 더 int형 객체로 변환해준다.
참고로 파이썬의 math 모듈은 내장 모듈(built-in module)로, 파이썬이 기본적으로 제공하는 라이브러리 중 하나이다. 그래서 다른 모듈처럼 파일 시스템에 직접적으로 보이지 않을 수 있습니다. 일반적으로 stdio.py처럼 사용자가 추가한 외부 모듈이나 파일은 site-packages 폴더에 저장되지만, 내장 모듈은 파이썬 설치 경로 내에 통합되어 있기 때문에 일반적인 폴더에서 확인할 수 없다. 그래서 math 모듈의 함수를 구경하러 가고 싶다면 파이썬이 기본적으로 제공하는 내장 모듈을 확인할 수 있는 파이썬이 설치된 디렉터리로 가보아야한다.
- 파이썬 내장 모듈 위치 확인하는 방법: 파이썬에서 math 모듈이 어디에 있는지 확인하려면, 아래 코드를 사용해서 경로를 확인할 수 있다.
import math
print(math.__file__)
위 코드로 보이지 않는다면 아래 코드로 sys 모듈을 사용하여 Python의 설치 경로를 확인해서 찾아야한다. 이 방법으로 Python 인터프리터가 어디에 설치되어 있는지 확인할 수 있을 것이다. math 모듈은 Python 인터프리터 내부에 포함되어 있기 때문이다.
import sys
print(sys.executable)
이걸로 위치를 찾아서 들어가보면 Lib라는 폴더가 있고 여기에 내장 라이브러리가 있다. Python의 내장 라이브러리들은 보통 Python 설치 경로 내에 있는 Lib 폴더 안에 위치하게 되는데 이 경우, Lib 폴더 내에서 math 모듈이 제공된다. 그런데 math 모듈의 코드가 내장된 C 코드로 존재하는 경우도 많아서 실제 Python 파일을 직접 확인할 수는 없을 수도 있다. math 모듈 파일이 보이지 않는다면 아마 이런 이유에서일 것이다. 실제로 나의 경우에도 바로 파일 확인에는 실패했다. 여기 바로 위에 언급된 대로 math 모듈은 C로 작성된 내장 모듈이라 실제 .py 파일은 보이지 않다고 한다.\
이외에도 파이썬에 존재하는 내장 모듈(예: math, sys, os 등)은 Python 인터프리터에 기본적으로 포함되어 있는 라이브러리이다. 이들은 Python 코드로 구현된 것뿐만 아니라 C로 구현된 모듈도 포함하는데. C로 구현된 내장 모듈은 성능을 최적화하려는 목적에서 만들어 진 것이다. math 모듈이 C로 작성된 이유는 수학적 계산을 빠르게 수행할 수 있도록 하기 위함이다. 예를 들어, math.sqrt()는 제곱근을 계산하는 함수인데, 이를 C로 구현하면 Python로 구현하는 것보다 훨씬 빠르다.
C로 작성된 모듈들은 Python 인터프리터와 동적으로 링크된 라이브러리로 컴파일되게 된다. 그러므로 Python에서 import math를 호출하면, Python은 해당 모듈을 C로 작성된 라이브러리에서 동적으로 로드하게되고. 이 때문에 실제 파일로 math.py 파일을 찾을 수 없는 것이다. 대신, C로 컴파일된 _math 또는 libmath와 같은 C 라이브러리 파일이 실제로 해당 모듈을 구현하는 부분이라고 볼수 있다.
Python이 시작되면, 내장 모듈들(예: math, sys 등)은 Python 인터프리터의 C 확장 모듈로 로드되게 된다. 이때 Python 코드로 작성된 것들이 아닌 C 코드로 작성된 모듈들은 .py 파일이 아니라 동적 라이브러리(.pyd 또는 .so 파일 등)로 존재하고, 그 안에서 구현된 함수들을 Python이 호출하게 되는 것이다.
예를 들어, math.sqrt() 함수는 C로 작성된 코드로, Python에서 호출했을 때 해당 C 코드가 실행되는데. 이 함수는 Python 인터프리터가 제공하는 C API를 통해 Python 환경에 맞게 호출되고. Python 코드에서 사용되는 내장 모듈들은 Python 인터프리터가 제공하는 C API를 사용하여 Python과 C의 연동을 가능하게 해준다.
따라서 math 모듈처럼 C로 작성된 내장 모듈은 .py 파일이 아니라 컴파일된 C 코드로 이루어져 있기 때문에 일반적으로 파일 시스템에서 찾을 수 없는 것이다.
다음은 Python에서 C로 작성된 몇 가지 내장 모듈의 예이다.
- math: 수학적 함수들 (예: sqrt, sin, cos, 등)
- sys: Python 인터프리터와 상호작용하는 함수들 (예: sys.argv, sys.exit() 등)
- os: 운영 체제와 관련된 함수들 (예: 파일 시스템 접근 등)
이러한 모듈들은 Python 인터프리터가 내장된 C 코드를 호출해서 빠르고 효율적인 처리를 할 수 있도록 도와준다고 할 수 있다.
결과적으로 C로 작성된 math 모듈의 소스 코드나 해당 파일을 직접 찾는 것은 일반적인 파일 시스템에서 .py 파일처럼 쉽게 찾을 수 있는 것은 아니지만 C로 구현된 math 모듈의 소스 코드나 컴파일된 바이너리 파일은 특정 경로에서 확인할 수 있는 방법이 있다.
1. Python 소스 코드에서 C 코드 찾기
Python의 math 모듈은 CPython이라는 Python 구현체에서 C로 작성된 코드이다. Python 인터프리터의 소스 코드를 직접 찾아보면, 그 안에 C로 작성된 수학 함수들이 포함되어 있는 걸 알 수 있다. Python의 소스 코드는 공개되어 있고, GitHub에서 확인할 수 있다.
방법:
- Python GitHub Repository: CPython GitHub Repository
- Python의 공식 GitHub 저장소에서 C 소스 코드를 확인할 수 있다.
- math와 관련된 C 코드가 Modules 디렉토리 내에 포함되어 있다. 예를 들어, math 함수들이 구현된 파일을 찾을 수 있다. https://github.com/python/cpython/tree/main/Modules
cpython/Modules at main · python/cpython
The Python programming language. Contribute to python/cpython development by creating an account on GitHub.
github.com
2. Python을 빌드할 때 사용된 C 파일
Python을 소스 코드에서 빌드할 때, math 관련 C 코드 파일은 Python 소스에 포함되어 있다. Python의 소스 코드를 다운로드하여 빌드하면, C로 작성된 여러 라이브러리 파일들이 함께 생성된다.
방법:
- Python 공식 사이트에서 소스 다운로드: Python Source Code
- Python 소스 코드를 다운로드하고, Modules/mathmodule.c 같은 경로에서 C로 작성된 수학 함수들을 찾을 수 있다.
3. C 확장 모듈을 사용하여 직접 확인하기
Python에서 C로 작성된 모듈은 종종 .pyd 또는 .so 확장자를 가진 동적 라이브러리 파일로 제공된다. 이러한 파일들은 Python 인터프리터와 함께 제공되며, Python 코드를 실행할 때 동적으로 로드된다.
방법:
- 확장 모듈로 C 코드 확인: Python 인터프리터가 실행될 때 math 모듈을 동적으로 로드하므로, Python에서 import math를 했을 때 실제로 math 모듈이 C 코드로 구현된 동적 라이브러리가 로드된다. 이를 확인하려면, Python 인터프리터가 로드하는 .pyd 또는 .so 파일을 확인해야한다.
4. Python의 math 모듈과 C 라이브러리의 연관
Python의 math 모듈은 C로 구현된 라이브러리를 사용하며, 실제 수학적 계산은 C의 libm 라이브러리에서 제공하는 함수를 사용한다. Python의 math 모듈은 libm 라이브러리를 API를 통해 호출하게 된다.
방법:
- libm 라이브러리 찾기: libm은 C 라이브러리의 일부로, 다양한 수학적 함수들 (sqrt, sin, cos 등)을 제공하는데. 이 라이브러리는 대부분의 리눅스 시스템에서 /usr/lib/ 또는 /lib/ 경로에 있다. Windows에서는 비슷한 역할을 하는 math.h 파일이 시스템에 내장되어 있다..
5. C로 구현된 math 모듈의 직접 컴파일
만약 직접 C로 수학 함수들을 작성하고 Python에서 이를 사용하고 싶다면, Python에서 제공하는 C API를 사용하여 C 확장 모듈을 작성할 수 있다. 이렇게 작성한 C 확장 모듈을 Python에서 사용할 수 있다.
방법:
- Python C API 사용법: Python은 C와 연동하기 위한 C API를 제공한다. 이를 통해 C로 수학 함수를 작성하고 이를 Python에서 사용할 수 있다.
요약
C로 작성된 math 모듈은 Python 인터프리터에서 직접 내장 모듈로 제공된다. 이 모듈의 소스 코드는 Python의 소스 코드나 GitHub에서 찾을 수 있고, C로 작성된 수학 함수들을 포함하는 파일들이 있다. C로 구현된 math 모듈은 동적 라이브러리 형태로 로드되기 때문에, 실제 파일 시스템에서 .py 파일처럼 확인하기는 어렵다. 그러나 C로 구현된 수학 함수들이 Python의 빌드 과정이나 소스 코드에 포함되어 있다는 점에서 확인할 수 있다.
만약 math.sqrt()함수는 음수의 제곱근을 구할 수 없으므로 ValuError 메시지가 나타나게 된다. 이를 알려주는 코드를 만든다면 간단하게 아래 처럼 나타낼 수 있다.
import sys
import stdio
import math
a = int(sys.argv[1])
b = int(sys.argv[2])
try:
result = math.sqrt(a)
result = math.sqrt(b)
except ValueError:
print("음수의 제곱근은 계산할 수 없습니다.")
아래처럼 입력받은 a와 b 중에서 1가지만이라도 음수라면 아래와 같이 음수의 제곱근은 계산할 수 없다고 나온다.
import sys
import stdio
import math
a = int(sys.argv[1])
b = int(sys.argv[2])
try:
result_a = math.sqrt(a)
print(result_a)
result_b = math.sqrt(b)
print(result_b)
except ValueError:
print("음수의 제곱근은 계산할 수 없습니다.")
이렇게 하면 a, b를 입력받은 다음에 구할 수 있으면 구해서 제곱근을 출력해주고 음수인 것은 오류 메시지를 출력해준다.
여기서 알 수 있는 건 try문에서 먼저 시행되는 줄이 ValueError가 발생하면 그 다음 줄은 실행하지 않고 바로 except로 넘어간다. 만약 먼저 시행되는 줄이 맞다면 우선 그 안에서 순차적으로 시행하게된다.
만약 a, b 구할 수 있다면 구하고 음수인 수는 음수의 제곱근을 계산할 수 없습니다를 출력하게 하려면 아래처럼 하면 된다.
import sys
import stdio
import math
a = int(sys.argv[1])
b = int(sys.argv[2])
# 음수 체크 후 제곱근 계산
try:
if a < 0:
raise ValueError("음수의 제곱근은 계산할 수 없습니다.") # a가 음수일 경우 예외 발생
result_a = math.sqrt(a)
print(f"a의 제곱근: {result_a}")
except ValueError as e:
print(f"a: {e}") # a에 대한 에러 메시지 출력
try:
if b < 0:
raise ValueError("음수의 제곱근은 계산할 수 없습니다.") # b가 음수일 경우 예외 발생
result_b = math.sqrt(b)
print(f"b의 제곱근: {result_b}")
except ValueError as e:
print(f"b: {e}") # b에 대한 에러 메시지 출력
만약 먼저 a, b 둘 중 하나가 음수인지 확인해서 하나만 음수라도 바로 프로그램을 종료하고 싶다면 아래처럼 하면 된다.
import sys
import stdio
import math
a = int(sys.argv[1])
b = int(sys.argv[2])
# 둘 중 하나라도 음수일 경우 제곱근 계산을 중지하고 메시지 출력
if a < 0 or b < 0:
print("음수가 있어서 제곱근 계산이 불가능합니다.")
else:
# 둘 다 양수일 경우 제곱근 계산
result_a = math.sqrt(a)
print(f"a의 제곱근: {result_a}")
result_b = math.sqrt(b)
print(f"b의 제곱근: {result_b}")
'컴퓨터이야기 > 파이썬프로그래밍' 카테고리의 다른 글
부동소수점 오류 간단한 예시 sin(θ)^2+cos(θ)^2=1 (0) | 2025.03.04 |
---|---|
프롬프트 상에서 파이썬 간단한 코딩 실행하기 (0) | 2025.03.04 |
파이썬 모듈에 writeln 함수 추가하기 (1) | 2025.02.16 |
명령 프롬프트로 Git 설치하기 (0) | 2025.02.16 |
python과 python3 명령어 둘 다 사용하기[PykoSpacing] (0) | 2025.02.16 |