Skip to content
This page has been auto-translated and may contain errors.View in English

숫자와 산술

거의 모든 프로그램에서 숫자를 다룹니다. 쇼핑 카트는 총액을 계산하고, 게임은 점수를 업데이트하고, 스크립트는 어떤 일이 몇 번 일어났는지 셉니다. Python은 종이에 하는 수학처럼 작동하는 산술 연산자를 제공하며, 처음부터 알아두면 좋은 추가 연산자도 몇 개 있습니다.

Python의 산술 연산자는 표준 연산자와 정수 나눗셈, 나머지, 거듭제곱을 포함합니다. 다른 언어와 달리 몇 가지 동작이 실제로 중요한 방식으로 다릅니다. /는 항상 float를 반환하고, 나눗셈으로 내림할 때는 음의 무한대 방향으로 내림하며, 나머지는 진정한 나머지 의미론을 따릅니다.

Python 정수는 오버플로우가 없습니다(고정 크기 정수가 있는 언어에서 발생하는 래핑이나 오류가 없음). 메모리가 허용하는 한 크기가 커집니다. 부동소수점 수는 일반적인 배정밀도 십진수이며 대부분의 작업에는 충분하지만 금전에는 절대 정확하지 않습니다. 산술 연산자는 많은 언어가 복사하는 C 관례가 아닌 수학적 정의를 따릅니다. //는 정수 나눗셈(음의 무한대 방향으로 내림)이고 %는 피제수가 아닌 제수의 부호를 가집니다. 두 선택 모두 입력이 양수든 음수든 같은 결과를 유지하므로, 순환과 래핑에서 원하는 동작입니다.

연산자

수학의 네 가지 연산자(+, -, *, /)는 정확히 예상하는 대로 작동합니다. Python은 세 개의 추가 연산자를 제공하며, 이들을 자주 사용하게 됩니다. 정수 나눗셈, 나머지, 거듭제곱입니다.

기본 네 개의 연산자는 예상대로 작동하며 한 가지 주목할 점이 있습니다. /는 결과가 정수일 때도 항상 float를 반환합니다. 세 개의 추가 연산자는 추가 작업 없이 할 수 있는 것을 확장합니다.

각 연산자는 던더 메서드(이중 밑줄로 이름을 지은 메서드로 Python이 내부적으로 호출함)와 연결됩니다. +__add__, //__floordiv__, %__mod__, **__pow__ 등입니다. 실제 장점은 자신의 클래스가 이 메서드를 정의하면 내장 숫자처럼 직접 +*와 함께 작동할 수 있다는 것입니다. intfloat를 한 번에 섞으면 항상 float가 되고, /는 입력이 무엇이든 float를 반환합니다.

python
price = 12.99
quantity = 3

print(price * quantity)   # 38.97
print(price + 2)          # 14.99
print(price - 1.00)       # 11.99
연산자이름예시결과
+덧셈5 + 38
-뺄셈5 - 32
*곱셈5 * 315
/나눗셈5 / 31.6666...
//정수 나눗셈5 // 31
%나머지5 % 32
**거듭제곱5 ** 3125
Juno연산자+, -, *, /는 종이 수학처럼 작동합니다. 세 개의 추가 연산자는 초반에 배울 가치가 있습니다. //는 정수로 나누고, %는 나머지를 주고, **는 거듭제곱합니다. 저는 예상했던 것보다 %를 훨씬 자주 사용합니다.
Juno연산자 네 가지 기본 연산자는 예상대로 작동하며 한 가지 규칙을 기억하세요. /는 항상 float를 반환합니다. 추가 연산자는 //는 정수 나눗셈, %는 나머지, **는 거듭제곱입니다. 각각이 헬퍼를 작성하는 수고를 덜어줍니다.
Juno연산자 모든 연산자는 던더 메서드로 라우팅되므로 __add____mul__을 정의한 클래스는 바로 +*로 플러그인됩니다. intfloat가 섞이면 항상 float로 확대되고, /는 입력이 무엇이든 float를 반환합니다.

나눗셈: / vs //

/는 정확한 십진 결과를 제공하며, 답이 정수일 때도 그렇습니다. //는 소수 부분을 버리고 음의 무한대 방향으로 내립니다. 양수의 경우 십진 부분을 자르는 것과 같지만, 음수의 경우 0에서 더 멀어집니다.

/는 항상 float를 반환하며, 입력이 정수든 상관없습니다. //는 결과의 floor를 반환합니다. 즉, 실제 결과 이하인 가장 큰 정수입니다. 양수의 경우 truncation과 같습니다. 음수의 경우는 그렇지 않습니다.

/는 진정한 나눗셈이고 항상 float를 반환합니다. //는 floor 나눗셈입니다. 많은 다른 언어처럼 0을 향해 자르는 것이 아니라 실제 몫을 음의 무한대 방향으로 반올림합니다. 실제로 중요한 이유는 Python의 //%가 모든 정수 입력(음수 포함)에 대해 a == (a // b) * b + (a % b)를 만족하기 때문입니다. Truncating 나눗셈은 음수에서 이 항등식을 깨뜨리므로, 순환이나 래핑 로직을 특수하게 처리하지 않아도 여기서 올바르게 작동합니다.

python
10 / 2     # 5.0   (항상 float, 정확히 나누어도)
10 / 3     # 3.3333333333333335

10 // 3    # 3
7 // 2     # 3
-7 // 2    # -4    (음의 무한대 방향으로 내림, 0 방향이 아님)

대부분 양수에서 //를 사용할 것입니다. 음수가 나타날 때를 대비해 음수 동작을 염두에 두세요.

Juno나눗셈: / vs ///는 항상 소수를 반환합니다. 4 / 22.0이어도 그렇습니다. //는 소수 부분을 버리지만 음수를 주의하세요. -7 // 2-3이 아닌 -4입니다. 내림하기 때문입니다. 처음 해봤을 때 저를 당황하게 했어요.

Python은 이를 floor 나눗셈이라고 부릅니다. 수학의 floor 함수를 적용하기 때문입니다. 다른 언어는 0을 향해 자르므로 음수에서 다른 결과를 줍니다. //이라는 이름은 힌트입니다. 나누고, 그 다음 내립니다.

Juno나눗셈: / vs ///는 항상 float를 반환합니다. 4 / 22.0입니다. //는 truncating 대신 내림하므로 -7 // 2-4입니다. 양수의 경우 둘이 같아 보이고, 음수에서만 차이가 납니다.

//floor(a / b)를 계산하며, truncation이 아닙니다. 부동소수점 수에서도 작동합니다. 7.5 // 23.0이고, floor된 몫이 int가 아닌 float로 반환됩니다.

Juno나눗셈: / vs ////는 몫을 내림하므로 모든 입력에서 a == (a // b) * b + (a % b)를 만족합니다. 음수도 포함입니다. 이것이 순환 로직에서 의존할 성질입니다. float 피연산자는 //가 float를 반환하게 합니다. 예를 들어 7.5 // 23.0입니다.

나머지 연산자 %

%는 정수 나눗셈 후 남은 것을 제공합니다. 10 // 33이면(3이 10에 3번 들어가므로), 10 % 31입니다(3 × 3 = 9이고 10 - 9 = 1이므로). 가장 흔한 사용처는 숫자가 짝수인지 홀수인지 확인하는 것입니다.

%는 modulo 연산자입니다. 짝수/홀수 확인이 가장 흔한 사용처이지만, 순환이나 래핑이 필요한 모든 문제에 일반화됩니다. 카운터를 범위 내에 유지하거나, 항목을 그룹에 분배하거나, 수열을 반복합니다. 패턴은 항상 value % limit이며, 0에서 limit - 1 사이의 값을 반환합니다.

Python의 %는 진정한 modulo입니다. 결과는 항상 제수의 부호를 가집니다. 많은 다른 언어는 피제수의 부호를 가지므로, Python이 -7 % 3에 대해 2를 줄 때 -1을 줄 것입니다. Python의 답은 modulo를 a - (a // b) * b로 정의하고 //가 음의 무한대를 향해 내림하기 때문에 나옵니다. 이점은 value % limitvalue가 음수일 때도 0에서 limit - 1 범위에 유지되므로, 리스트 끝을 래핑하는 인덱스가 보호 조건 없이 범위에 들어온다는 것입니다.

python
10 % 3    # 1
10 % 2    # 0  (정확히 나누어짐)
10 % 7    # 3

6 % 2     # 0  (짝수)
7 % 2     # 1  (홀수)
Juno나머지 연산자 %%는 정수 나눗셈 후 남은 것입니다. 10 % 31인데 3이 10에 세 번 들어가고 1이 남기 때문입니다. 대부분 짝수/홀수 확인으로 만날 것입니다. n % 2는 짝수일 때 0, 홀수일 때 1입니다.
Juno나머지 연산자 %%는 modulo이며, 짝수/홀수를 넘어 갑니다. 어떤 값을 범위 내에 유지해야 할 때, value % limit0부터 limit - 1로 래핑합니다. 카운터, 그룹 할당, 반복 순환, 모두 같은 모양입니다.
Juno나머지 연산자 %%는 제수의 부호를 따르므로 -7 % 32이며 -1이 아닙니다. 이것이 value % limit이 음수 입력에서도 범위에 유지되게 하며, 래핑 인덱스를 위한 보호 조건이 필요 없습니다.

거듭제곱 **

**는 숫자를 거듭제곱합니다. Python에서는 ^ 기호가 다른 의미이므로 두 개의 별표를 사용하세요.

**는 거듭제곱입니다. 부동소수점 수에도 작동하므로, 별도의 함수 호출 없이 분수 거듭제곱으로 제곱근을 표현할 수 있습니다.

**는 거듭제곱이며, 분수 거듭제곱 형태가 유용합니다. n ** 0.5는 아무것도 import 없이 제곱근입니다. 두 int 피연산자는 int를 주고, 어떤 float 피연산자든 float를 줍니다. 큰 값이나 정밀한 작업에 도달하기 전에 알아야 할 한 가지가 있습니다. 9 ** 0.5는 float 수학을 거쳐가므로 일부 입력에서 2.9999999999999996에 착지할 수 있습니다. 정확성이 중요할 때는 정수 제곱근의 경우 math.isqrt(), math.pow()가 고려할 도구입니다. 이는 모듈 장에서 다룹니다.

python
2 ** 10    # 1024
3 ** 3     # 27
9 ** 0.5   # 3.0  (제곱근: 0.5의 거듭제곱으로 올림)
Juno거듭제곱 ****는 숫자를 거듭제곱하므로 2 ** 101024입니다. 분수 거듭제곱은 제곱근을 줍니다. 9 ** 0.53.0입니다. 한 가지 함정은 기호입니다. ^가 아닌 **를 사용하세요. Python에서는 ^가 다른 의미입니다.
Juno거듭제곱 ****는 거듭제곱이며 float를 받으므로 9 ** 0.5는 별도 함수 호출 없이 제곱근을 줍니다. 분수 거듭제곱 형태를 인라인에서 빨리 제곱근을 원할 때 사용하세요.
Juno거듭제곱 ** 두 int는 int를 주고, 어떤 float는 float를 줍니다. ** 0.5 제곱근 트릭의 함정은 float 수학을 거쳐 떠내려갈 수 있다는 것입니다. 정확성이 필요할 때 math.isqrt()math.pow()를 사용하세요.

연산자 우선순위

Python은 표준 수학 순서를 따릅니다. 거듭제곱 먼저, 그 다음 곱셈과 나눗셈, 그 다음 덧셈과 뺄셈입니다. 확실하지 않으면 괄호를 사용하세요. 의도를 명확하게 하고 비용이 들지 않습니다.

Python은 표준 PEMDAS/BODMAS 순서를 따릅니다. 사람들을 걸려 넘게 하는 부분은 /, //, %이 모두 같은 우선순위를 가지고 섞일 때 왼쪽에서 오른쪽으로 평가된다는 것입니다. 괄호는 무료이며, 순서가 한눈에 명확하지 않을 때마다 사용하세요.

산술 연산자 중 우선순위(높은 것부터 낮은 것으로): **, 그 다음 단항 -(단일 값 앞의 빼기 기호), 그 다음 * / // %(같은 레벨일 때 왼쪽에서 오른쪽), 그 다음 + -. 실제 코드에서 깨무는 한 가지 함정은 -2 ** 2-(2 ** 2)이며 -4라는 것입니다. **이 선행 빼기보다 더 단단하게 묶이기 때문입니다. 음수일 수 있는 값을 제곱할 때마다, 부호가 틀려도 경고하는 오류 없이 (-2) ** 2로 괄호를 넣으세요.

python
2 + 3 * 4      # 14, 20이 아님
2 ** 3 + 1     # 9,  512가 아님
10 - 4 / 2     # 8.0, 3.0이 아님

(2 + 3) * 4    # 20
10 / (2 + 3)   # 2.0
Juno연산자 우선순위 종이 수학과 같은 순서입니다. 거듭제곱 먼저, 그 다음 곱하고 나누기, 그 다음 더하고 빼기입니다. 순서가 한눈에 명확하지 않으면 괄호를 추가하세요. 비용이 들지 않고 정확히 의도한 바를 나타냅니다.
Juno연산자 우선순위 표준 PEMDAS 순서이며, 한 가지 걸림돌이 있습니다. /, // 그리고 %는 모두 같은 레벨에 있고 섞일 때 왼쪽에서 오른쪽으로 실행됩니다. 그 왼쪽에서 오른쪽 규칙이 사람들이 잘못 읽는 부분이므로, 그룹화가 명확하지 않을 때마다 괄호를 넣으세요.
Juno연산자 우선순위 함정은 단항 빼기가 **보다 느슨하게 묶인다는 것입니다. 그래서 -2 ** 2-4입니다. 음수일 수 있는 모든 것을 (-2) ** 2로 제곱하세요. 그래야 경고할 오류 없이 부호가 뒤집히지 않습니다.

intfloat는 어떻게 상호작용하나요

Python은 일관된 규칙을 가지고 있습니다. /는 항상 소수를 반환하며, 4 / 22.0입니다. 정수와 소수를 섞는 모든 연산도 소수를 줍니다. 정수가 필요할 때 //를 사용하거나 int()로 변환하세요.

타입 규칙은 예측 가능합니다. /는 항상 float를 반환합니다. //%는 두 정수에서 int를 반환합니다. intfloat를 섞는 모든 연산은 float를 반환합니다. 이는 4 / 22.0이며 2가 아니라는 뜻입니다. 정수가 필요할 때(예를 들어 인덱스로 사용)가 중요합니다.

규칙은 고정되어 있으며 내재화할 가치가 있습니다. int는 둘이 섞일 때마다 float로 확대되고, /는 항상 float를 반환하고, //은 두 피연산자가 모두 int일 때만 int를 반환합니다. 이것이 방지하는 버그는 float이 정수가 필요한 것으로 몰래 들어가는 것입니다. 예를 들어 리스트 인덱스나 딕셔너리 키에는 2.02가 동일하지 않습니다. 계산이 float를 만들 수 있고 int가 필요할 때, 전체 계산이 정확히 나올 것을 기대하기보다 그 지점에서 int()로 변환하세요.

python
4 / 2      # 2.0   (float, 항상)
4 // 2     # 2     (int)
4 + 2      # 6     (int)
4 + 2.0    # 6.0   (float)
4 * 0.5    # 2.0   (float)
Junoint와 float는 어떻게 상호작용하나요/는 항상 소수를 주므로 4 / 22가 아닌 2.0입니다. 정수와 소수를 어디서든 섞으면 소수가 나옵니다. 정수가 필요할 때 //를 사용하거나 int()로 감싸세요.
Junoint와 float는 어떻게 상호작용하나요/는 항상 float이고, //%는 두 int에서 int로 유지되며, 어떤 intfloat와 섞으면 float가 나옵니다. 사람들을 잡아내는 것은 4 / 2가 인덱스를 원할 때 2.0이라는 것입니다.
Junoint와 float는 어떻게 상호작용하나요/에서 떠도는 float는 인덱스나 딕셔너리 키와 같이 정확한 int가 필요한 모든 것을 깨뜨립니다. 여기서 2.02가 아닙니다. 계산이 float를 만들 수 있고 int가 필요할 때, 그 경계에서 int()로 변환하고 나눗셈이 정확히 나올 것을 신뢰하지 마세요.

Float 정밀도

거의 모든 사람을 어느 시점에서 놀라게 하는 함정이 있습니다.

python
0.1 + 0.2   # 0.30000000000000004

그 작은 오류는 Python 버그가 아닙니다. 컴퓨터는 십진수를 이진수로 저장하며, 0.1 같은 일부 값은 정확히 표현할 수 없습니다. 이는 1/3을 십진수로 정확히 쓸 수 없는 것과 유사합니다. 대부분의 일상적인 계산에는 중요하지 않습니다. 돈을 표시할 때 round() 또는 :.2f 형식 지정자가 출력을 깔끔하게 유지합니다.

Float는 대략 15~16자리의 유효 십진 정밀도를 제공합니다. 부정확함은 일부 분수가 이진수로 정확히 저장될 수 없기 때문에 나타나므로 0.1 + 0.20.30000000000000004를 생성합니다. 떠내려감은 원시 값을 검사할 때만 나타납니다. :.2fround()로 형식화하면 출력에서 숨겨집니다.

금융 작업에서 센트 분수가 축적되는 경우, Python은 표준 라이브러리의 decimal.Decimal로 정확한 base-10 산술을 제공합니다. 이는 모듈 장에서 다룹니다.

float는 이진(base 2)으로 숫자를 저장하며, 분모가 2의 거듭제곱이 아닌 분수(1/10 같은)는 정확한 이진 형태가 없습니다. 이는 1/3이 십진 형태가 없는 것과 같은 방식입니다. 이것이 0.1 + 0.20.30000000000000004에 착지하는 전체 이유입니다. 연산당 오류는 작지만 긴 산술 체인에 걸쳐 축적되므로, 같은 합을 계산하는 두 가지 방법이 마지막 몇 자리에서 불일치할 수 있습니다.

버그를 방지하는 규칙. 절대 float를 돈으로 사용하지 말고, 절대 ==로 float를 정확히 비교하지 마세요. 정확한 base-10 산술이 필요할 때 decimal.Decimal을(를) 사용하세요(청구, 회계). 또는 전혀 반올림 없이 정확한 비율이 필요할 때 fractions.Fraction을(를) 사용하세요. 둘 다 Python 표준 라이브러리에 있으며 모듈 장에서 다룹니다.

JunoFloat 정밀도 컴퓨터는 십진수를 이진수로 저장하며, 0.1 같은 일부 값은 정확한 이진 형태가 없으므로 0.1 + 0.20.30000000000000004가 됩니다. 이는 Python 버그가 아니며 모든 언어가 이를 합니다. 일상적인 출력의 경우 round() 또는 :.2f가 깔끔하게 유지합니다.
JunoFloat 정밀도 이진수는 모든 십진수를 정확히 보유할 수 없으므로 0.1 + 0.20.30000000000000004로 떠내려갑니다. 대부분의 수학에는 괜찮으며, :.2fround()가 디스플레이를 정돈합니다. 센트가 더해질 때 decimal.Decimal로 전환하세요.
JunoFloat 정밀도 버그를 구하는 규칙: 돈에는 float가 없고, float에는 절대 ==가 없습니다. 오류가 연산 체인에 축적되기 때문입니다. 정확한 base-10에는 decimal.Decimal을, 정확한 비율에는 fractions.Fraction을 사용하세요.

읽기 쉬운 숫자 리터럴

Python은 긴 숫자를 더 읽기 쉽게 만들기 위해 숫자 리터럴에 밑줄을 넣을 수 있습니다. Python은 이를 완전히 무시합니다. 이는 당신을 위한 것입니다.

밑줄은 숫자 리터럴의 어디든 유효하며, 파싱 중에 제거되고 값에 영향이 없습니다. 상수의 천 자리 구분 기호와 이진 또는 16진 리터럴의 자릿수 그룹화에 유용합니다.

밑줄은 Python이 보기 전에 제거되므로 값에 영향이 없습니다. 이들은 정수, 부동소수점, 기반 리터럴(0xFF_FF, 0b1010_0001, 1_234.567_890)에서 작동하므로, 십진수의 천 자리뿐만 아니라 16진 상수에서 바이트를 그룹화하는 데 유용합니다. 유일한 제한: 밑줄은 시작, 끝 또는 소수점이나 지수 표식 옆에 있을 수 없습니다.

python
population = 8_100_000_000
distance_km = 384_400
pi_approx = 3.141_592_653
Juno읽기 쉬운 숫자 리터럴 긴 숫자에 밑줄을 떨어뜨려 읽기 쉽게 만드세요. 8_100_000_0008100000000과 같은 값입니다. Python은 이를 완전히 무시하며, 해석기가 아닌 당신의 눈을 위한 것입니다.
Juno읽기 쉬운 숫자 리터럴 밑줄은 숫자 리터럴의 어디든 유효하며 파싱 시간에 사라지므로 값은 변하지 않습니다. 상수의 천 자리 구분 기호와 이진 또는 16진에서의 자릿수 그룹화에 유용합니다.
Juno읽기 쉬운 숫자 리터럴 밑줄은 정수, 부동소수점, 기반 리터럴을 통해 화장품이므로 0xFF_FF0b1010_0001이 더 깔끔합니다. 유일한 규칙: 시작, 끝 또는 소수점이나 지수 표식 옆에 없습니다.

유용한 내장 함수

abs()

abs()는 절댓값을 반환합니다. 항상 양수이며, 입력의 부호와 상관없습니다. 숫자가 0에서 얼마나 멀리 떨어져 있는지, 어느 방향인지 신경 쓸 때 사용하세요.

abs()는 숫자의 크기를 반환합니다. 정수와 부동소수점 수에 작동합니다. 거리 계산, 오차 한계, 방향이 관계없고 값의 크기만 필요한 모든 상황에 유용합니다.

abs()는 숫자의 크기를 반환하며, 반환 타입이 입력과 일치합니다. int가 들어오면 int가 나가고, float가 나갑니다. 일상적인 사용은 부호를 신경 쓰지 않고 두 값이 목표에서 얼마나 멀리 떨어져 있는지 비교하는 것입니다. 예를 들어 abs(measured - expected) < tolerance는 오차 한계 확인이므로, 부호 범위 주위의 두 비교보다 더 명확하게 읽힙니다.

python
abs(-5)     # 5
abs(3.7)    # 3.7
abs(-0.5)   # 0.5
Junoabs()abs()는 부호를 제거하고 양수 크기를 반환합니다. abs(-5)5이고, abs(3.7)3.7입니다. 숫자가 0에서 얼마나 멀리 떨어져 있는지, 어느 방향인지 신경 쓸 때 사용하세요.
Junoabs()abs()intfloat의 크기를 제공합니다. 방향이 삭제됩니다. 거리와 오차 한계 확인을 쓰는 깔끔한 방법이며, 부호가 질문의 일부가 아닌 모든 곳입니다.
Junoabs()abs()는 입력 타입을 유지하며, intint로 유지됩니다. 기억할 패턴은 abs(measured - expected) < tolerance입니다. 부호 범위 주위의 두 비교 대신 하나의 오차 한계 확인입니다.

round()

round()는 기본적으로 가장 가까운 정수로 반올림합니다. 두 번째 인수를 전달하여 특정 십진 자릿수를 유지하세요.

python
round(3.7)          # 4
round(3.2)          # 3
round(3.14159, 2)   # 3.14

알아두면 좋은 한 가지: round(2.5)3이 아닌 2입니다. Python은 값이 두 옵션의 정확히 중간일 때 가장 가까운 짝수로 반올림합니다.

round()banker's rounding을 사용합니다. 값이 정확히 중간일 때, 항상 올림이 아닌 가장 가까운 짝수로 반올림합니다. 이는 통계 작업에서 누적 오류를 최소화하지만, 0.5가 항상 올림될 것으로 예상하면 놀랄 수 있습니다.

python
round(2.5)   # 2  (가장 가까운 짝수로 반올림)
round(3.5)   # 4
round(4.5)   # 4  (5가 아님)
round(3.14159, 2)   # 3.14

round()는 round-half-to-even(banker's rounding)을 사용합니다. 정확한 타이는 항상 위가 아닌 가장 가까운 짝수 정수로 갑니다. 이것이 반올림 오류가 긴 그림 열을 한 방향으로 편향되지 않게 하므로 통계 작업의 기본값입니다. 두 가지 실질적 주의. 첫째, float 타이는 이진수에 있을 때 정확한 타이가 아닌 경우가 많으므로 round(2.675, 2)2.68이 아닌 2.67을 줍니다. 2.675를 정확히 저장할 수 없기 때문입니다. 둘째, 예측 가능한 통화 반올림이 필요할 때, float 위에서 round()에 의존하기보다 decimal.Decimal과 명시적 반올림 모드로 수행하세요.

python
round(2.5)   # 2
round(3.5)   # 4
round(4.5)   # 4
Junoround()round(x)는 가장 가까운 정수로 가고, round(x, n)n 십진 자릿수를 유지합니다. 놀라움: 정확히 중간에 앉은 값이 가장 가까운 짝수로 반올림되므로 round(2.5)3이 아닌 2입니다.
Junoround()round()는 banker's rounding을 사용하므로 정확한 하프는 가장 가까운 짝수로 갑니다. round(2.5)2이고, round(4.5)4입니다. 합계 작업을 절단하지만, 하프가 항상 올라간다고 생각했을 때 기대하세요.
Junoround() Banker's rounding에 이진수는 round(2.675, 2)2.67이므로, 2.675는 구석의 정확한 타이가 아닙니다. 통화의 경우, float 위에서 round()를 신뢰하기보다 decimal.Decimal과 선택한 모드로 반올림하세요.

divmod()

divmod()는 몫과 나머지를 한 번에 제공합니다. 튜플이라고 불리는 값의 쌍을 반환합니다(튜플과 집합 장에서 다룸). 한 번에 두 이름에 할당할 수 있습니다.

divmod(a, b)(a // b, a % b)과 같지만 한 단계에서 계산됩니다. 어차피 두 값이 모두 필요할 때 사용하세요. 페이지 나누기, 시간 변환, 또는 항목을 그룹에 분배할 때입니다.

divmod(a, b)는 나눗셈을 한 번 수행하고 floor 몫과 modulo 나머지를 쌍으로 반환하므로, //%를 통해 같은 나눗셈을 다시 계산하는 것을 피합니다. 어차피 양쪽이 모두 필요한 장소에서 가장 깔끔하게 읽힙니다. 시간 변환(divmod(seconds, 60)), 페이지 나누기, 또는 고정 크기 행 배치입니다.

python
divmod(10, 3)   # (3, 1): 몫 3, 나머지 1
divmod(7, 2)    # (3, 1)
divmod(9, 3)    # (3, 0)

quotient, remainder = divmod(10, 3)
print(quotient)    # 3
print(remainder)   # 1
Junodivmod()divmod(a, b)는 몫과 나머지를 함께 반환합니다. divmod(10, 3)(3, 1)입니다. quotient, remainder = divmod(10, 3)으로 한 번에 둘을 언팩할 수 있습니다.
Junodivmod()divmod(a, b)는 한 단계의 (a // b, a % b)입니다. 시간 변환이나 페이지 나누기 같은 두 조각이 모두 필요할 때, 나눗셈을 두 번 계산하기보다 사용하세요.
Junodivmod() 한 번의 나눗셈, 둘 다 결과합니다. divmod()는 별개의 //%의 중복 작업을 건너뜁니다. divmod(seconds, 60)이나 행 배치 같은 양쪽이 모두 필요한 곳에서 가장 잘 읽힙니다.

실제로

팁 계산기:

python
bill = 45.50
tip_rate = 0.18
tip = round(bill * tip_rate, 2)
total = round(bill + tip, 2)

print(f"Bill:  ${bill}")
print(f"Tip:   ${tip}")
print(f"Total: ${total}")

round()는 긴 십진 자릿수 실행이 아닌 돈처럼 출력을 보이게 합니다.

페이지 나누기를 위해 페이지를 세고 진행률을 백분율로 추적하기:

python
total_items = 153
items_per_page = 10

full_pages, leftover = divmod(total_items, items_per_page)
total_pages = (total_items + items_per_page - 1) // items_per_page

print(f"Full pages: {full_pages}, leftover: {leftover}")
print(f"Total pages needed: {total_pages}")   # 16
python
total_files = 847
processed_files = 312

percent = round(processed_files / total_files * 100, 1)
print(f"Progress: {processed_files}/{total_files} ({percent}%)")

천장 나눗셈 공식 (n + d - 1) // d는 float로 변환하지 않고 올림하는 표준 정수 트릭입니다.

Min-max 정규화와 백분율 변화는 데이터 작업에 지속적으로 나타나는 두 패턴입니다.

python
# min-max 정규화: 값을 0.0에서 1.0 범위로 스케일
value = 75
minimum = 0
maximum = 100

normalised = (value - minimum) / (maximum - minimum)
print(f"Normalised: {normalised:.2f}")   # 0.75

# 두 측정 간의 백분율 변화
before = 1_200
after = 1_380

change = (after - before) / before * 100
print(f"Change: {change:.1f}%")          # 15.0%

두 패턴 모두 비율로 감소합니다. 참조 범위 또는 참조 크기에 관계된 값입니다. float 정밀도는 대부분의 분석 작업에 충분합니다. 누적 오류는 계산이 수십 개의 연산을 체인화하거나 여러 차수의 크기로 다른 값을 포함할 때만 중요합니다.