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

수와 산술

docs.scrimba.com

수는 작성하는 거의 모든 프로그램에 나타납니다. 쇼핑 카트는 가격 합계를 계산합니다. 게임은 점수를 업데이트합니다. 스크립트는 어떤 일이 몇 번 발생했는지 세어봅니다. Python은 종이 수학처럼 작동하는 산술 연산자를 제공하며, 처음부터 알아야 할 몇 가지가 더 있습니다.

Python의 산술 연산자는 정수 나눗셈, 나머지, 지수 연산을 포함한 표준 집합을 다룹니다. 몇 가지 동작이 다른 언어와 다르며 실제로 중요합니다: /는 항상 float을 반환하고, 정수 나눗셈은 음의 무한대 방향으로 올림하며, 나머지는 참 나머지 의미론을 따릅니다.

Python 정수는 오버플로우가 없습니다(고정 크기 정수가 있는 언어에서 발생하는 래핑 또는 오류): 메모리가 허용하는 한 계속 커집니다. Float는 일반적인 배정밀도 소수이며 대부분의 작업에 충분하지만 금액에 대해서는 정확하지 않습니다. 산술 연산자는 많은 언어가 복사하는 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을 반환합니다(입력이 정수이든 관계없이). //는 결과의 바닥을 반환합니다: 참 결과보다 작거나 같은 가장 큰 정수입니다. 양수의 경우 이것은 절단과 같습니다. 음수의 경우 그렇지 않습니다:

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

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은 이를 정수 나눗셈이라고 합니다(수학 바닥 함수를 적용하기 때문). 다른 언어는 대신 0 방향으로 자르므로 음수에 대해 다른 결과를 줍니다. // 이름은 힌트입니다: 나누고 올림합니다.

Juno나눗셈: / vs ///는 항상 float을 반환합니다(4 / 22.0을 줍니다). //는 자르지 않고 올림하므로 -7 // 2-4입니다. 양수의 경우 두 개가 같아 보이며, 갭은 음수에서만 열립니다.

//floor(a / b)를 계산합니다. 절단이 아닙니다. float에도 작동합니다: 7.5 // 23.0입니다. 몫이 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이므로). 가장 흔한 사용은 숫자가 짝수인지 홀수인지 확인하는 것입니다.

%는 나머지 연산자입니다. 짝수/홀수 확인이 가장 흔한 사용이지만, 순환이나 래핑 문제로 일반화됩니다: 카운터를 범위 내에 유지하기, 항목을 그룹으로 분배하기, 시퀀스 반복하기. 패턴은 항상 value % limit이며, 이는 0limit - 1 사이의 값을 반환합니다.

Python의 %는 참 나머지입니다: 결과는 항상 제수의 부호를 가집니다. 많은 다른 언어는 피제수의 부호를 가지므로, Python이 2를 주는 곳에서 -7 % 3에 대해 -1을 줄 것입니다. Python의 답은 나머지를 a - (a // b) * b로 정의하고 //를 음의 무한대 방향으로 올림하는 것에서 나옵니다. 이득은 value % limit이 음수 value로도 0에서 limit - 1 사이에 유지되므로, 목록의 끝 주위를 래핑하는 인덱스는 보호 절 없이 범위 내에 착륙합니다.

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

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

지수 연산 **

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

**는 지수 연산입니다. float에도 작동하므로 별도 함수 호출이 아닌 분수 거듭제곱으로 근을 표현할 수 있습니다:

**는 거듭제곱하고, 분수 거듭제곱 형식이 편합니다: n ** 0.5는 아무것도 가져오지 않고 제곱근입니다. 두 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가 아닌 2.0이므로 정수가 필요할 때(예를 들어 인덱스로 사용)는 중요합니다.

규칙은 고정되어 있고 내재화할 가치가 있습니다: 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 / 2는 `2`가 아닌 `2.0`입니다. 어디서나 정수를 소수와 섞으면 소수가 나옵니다. 정수가 필요할 때는 //에 도달하거나 int()로 래핑하세요.
Junoint와 float이 상호작용하는 방법/는 항상 float이고, //%는 두 int에서 int로 유지되며, 모든 intfloat과 섞이면 float이 나옵니다. 사람들을 헷갈리게 하는 것은 `4 / 2`가 인덱스를 원할 때 `2.0`이라는 것입니다.
Junoint와 float이 상호작용하는 방법/에서의 보푸라기 float이 인덱스 또는 dict 키처럼 정확한 int가 필요한 것을 깨뜨립니다. 여기서 `2.0`은 `2`가 아닙니다. 전체 나눗셈이 나왔다고 믿기보다는 그 경계에서 int()로 변환하세요.

부동소수점 정밀도

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

python
0.1 + 0.2   # 0.30000000000000004

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

Float은 대략 15~16자리의 유효 소수 정밀도를 제공합니다. 부정확성은 일부 분수를 이진법으로 저장할 수 없기 때문에 표면화되므로 0.1 + 0.20.30000000000000004를 생성합니다. 표류는 원시 값을 검사할 때만 나타나고, :.2f 또는 round()로 포맷팅하면 출력에서 숨겨집니다.

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

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

버그를 방지하는 규칙: 돈을 위해 float을 절대 사용하지 말고, ==로 float을 절대 테스트하지 마세요. 정확한 10진 산술이 필요할 때(청구, 회계) 또는 반올림이 없이 정확한 비율이 필요할 때(예를 들어 fractions.Fraction) decimal.Decimal에 도달하세요. 둘 다 Python 표준 라이브러리에 제공되며, 모듈 장에서 다룹니다.

Juno부동소수점 정밀도 컴퓨터는 소수를 이진법으로 저장하고, `0.1` 같은 일부 값은 정확한 이진 형식이 없으므로 `0.1 + 0.2`는 `0.30000000000000004`로 나옵니다. 이는 Python 버그가 아니며 모든 언어가 이렇게 합니다. 일상적인 출력의 경우, `round()` 또는 `:.2f`가 깔끔하게 유지합니다.
Juno부동소수점 정밀도 이진법은 모든 소수를 정확히 유지할 수 없으므로 `0.1 + 0.2`는 `0.30000000000000004`로 표류합니다. 대부분의 수학에는 괜찮으며, `:.2f` 또는 `round()`가 표시를 깔끔하게 합니다. 센트가 더해질 때, `decimal.Decimal`로 전환하세요.
Juno부동소수점 정밀도 규칙이 당신을 저장합니다: 돈을 위해 float이 아니고, float을 절대 `==`하지 마세요. 정확한 10진법이 필요하면 `decimal.Decimal`을 사용하고, 정확한 비율이 필요하면 `fractions.Fraction`을 사용하세요.

읽을 수 있는 숫자 리터럴

Python은 큰 숫자를 더 읽기 쉽게 하기 위해 숫자 리터럴에 밑줄을 넣을 수 있게 합니다. Python은 완전히 무시합니다; 당신을 위한 것입니다:

밑줄은 숫자 리터럴의 어디든 유효하며 파싱 중에 제거되므로 값에 영향이 없습니다. 상수의 천 단위 구분자 및 이진 또는 16진 리터럴의 자리 그룹화에 유용합니다:

밑줄은 Python이 값을 보기 전에 제거되므로 0의 영향이 있습니다. 이들은 정수, float, 및 기반 리터럴(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읽을 수 있는 숫자 리터럴 밑줄은 정수, float 및 기반 리터럴을 통해 장식적입니다(0xFF_FF0b1010_0001이 더 깔끔하게 읽힙니다). 유일한 규칙: 시작, 끝 또는 소수점이나 지수 마커 옆에 있지 않습니다.

유용한 내장 함수

abs()

abs()는 절대값을 반환합니다: 입력의 부호에 관계없이 항상 양수입니다. 숫자가 0에서 얼마나 멀리 떨어져 있는지가 중요하고 어느 방향인지가 아닐 때 사용하세요.

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

abs()는 숫자의 크기를 반환하며, 반환 타입이 입력과 일치합니다: int이 들어가면 int가 나오고, float이면 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()는 `int` 또는 `float`의 크기를 주며, 방향은 버립니다. 거리와 오류 범위 확인을 작성하는 깨끗한 방법이며, 부호가 질문의 일부가 아닌 곳입니다.
Junoabs()abs()는 입력 타입을 유지하며, `int`는 `int`로 유지됩니다. 기억할 패턴은 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()은행원 올림을 사용합니다: 값이 정확히 중간일 때, 항상 올림하지 않고 가장 가까운 짝수로 올림합니다. 이는 통계 작업에서 누적된 오류를 최소화하지만 0.5가 항상 올림할 것으로 예상하면 놀랄 수 있습니다:

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

round()는 반올림-절반-짝수(은행원 올림)를 사용합니다: 정확한 동점은 항상 올림이 아닌 가장 가까운 짝수 정수로 갑니다. 이는 긴 숫자 열에서 올림 오류가 한 방향으로 편향되는 것을 방지하므로, 통계 작업의 기본입니다. 두 가지 실질적 주의사항. 첫째, float 동점은 이진법에 있으면 정확한 동점이 아니므로 round(2.675, 2)2.67을 줍니다(2.68이 아님). 2.675는 정확히 저장될 수 없기 때문입니다. 둘째, 통화 올림이 예측 가능해야 할 때, 부동소수점 위의 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()는 은행원 올림을 사용하므로 정확한 절반은 가장 가까운 짝수로 갑니다: round(2.5)는 `2`이고, round(4.5)는 `4`입니다. 통계 작업을 자르지만, 절반이 항상 올림할 것으로 예상할 때 예상하세요.
Junoround() 은행원 올림과 이진법이란 것은 `round(2.675, 2)`는 `2.67`입니다(`2.675`가 이진법 아래서 정확한 동점이 아니므로). 통화의 경우, float 위의 `round()`를 신뢰하기보다는 선택한 모드로 decimal.Decimal을 올림하세요.

divmod()

divmod()는 단일 호출에서 몫과 나머지를 모두 제공합니다. 튜플(튜플과 집합 장에서 다루어짐)인 값 쌍을 반환하며, 이를 한 번에 두 이름에 할당할 수 있습니다:

divmod(a, b)(a // b, a % b)와 동등하지만 단일 단계에서 계산됩니다. 어차피 두 값이 모두 필요할 때 사용하세요: 페이지 매김, 시간 변환, 또는 항목을 그룹으로 분배할 때.

divmod(a, b)는 나눗셈을 한 번 수행하고 바닥 몫과 나머지 모듈로를 쌍으로 반환하므로, //과 그 다음 %를 통해 같은 나눗셈을 다시 계산하는 것을 피합니다. 어차피 두 반쪽 모두를 원하는 곳에서 가장 깔끔하게 읽힙니다: 시간 변환(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으로 변환하지 않고 올림하기 위한 표준 정수 트릭입니다.

최소-최대 정규화 및 백분율 변화: 데이터 작업에서 끊임없이 나타나는 두 패턴:

python
# 최소-최대 정규화: 값을 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의 정밀도는 대부분의 분석 작업에 충분합니다; 누적된 오류는 계산이 수십 개의 연산을 연쇄하거나 많은 자릿수만큼 다른 값을 포함할 때만 중요합니다.