programing

파이썬에 // 연산자에 해당하는 천장이 있습니까?

bestprogram 2023. 5. 7. 12:03

파이썬에 // 연산자에 해당하는 천장이 있습니까?

나는 그것에 대해 알았습니다.//Python 3에서 바닥과 나눗셈을 수행하는 Python의 연산자입니다.

대신 천장으로 나누는 작업자가 있나요?(나는 그것에 대해 알고 있습니다./Python 3에서 부동 소수점 분할을 수행하는 연산자.)

아니요, 하지만 거꾸로 된 바닥 분할을 사용할 수 있습니다.¹

def ceildiv(a, b):
    return -(a // -b)

이것은 Python의 나눗셈 연산자가 바닥 나눗셈을 하기 때문에 작동합니다(정수 나눗셈이 분수 부분을 잘라내는 C와는 다릅니다).

다음은 시연입니다.

>>> from __future__ import division     # for Python 2.x compatibility
>>> import math
>>> def ceildiv(a, b):
...     return -(a // -b)
...
>>> b = 3
>>> for a in range(-7, 8):
...     q1 = math.ceil(a / b)   # a/b is float division
...     q2 = ceildiv(a, b)
...     print("%2d/%d %2d %2d" % (a, b, q1, q2))
...
-7/3 -2 -2
-6/3 -2 -2
-5/3 -1 -1
-4/3 -1 -1
-3/3 -1 -1
-2/3  0  0
-1/3  0  0
 0/3  0  0
 1/3  1  1
 2/3  1  1
 3/3  1  1
 4/3  2  2
 5/3  2  2
 6/3  2  2
 7/3  3  3

왜 수학 대신에 이것을?

math.ceil(a / b)부동 소수점 오류가 발생하기 때문에 은 조용히 잘못된 결과를 생성할 수 있습니다.예:

>>> from __future__ import division     # Python 2.x compat
>>> import math
>>> def ceildiv(a, b):
...     return -(a // -b)
...
>>> x = 2**64
>>> y = 2**48
>>> ceildiv(x, y)
65536
>>> ceildiv(x + 1, y)
65537                       # Correct
>>> math.ceil(x / y)
65536
>>> math.ceil((x + 1) / y)
65536                       # Incorrect!

일반적으로 부동 소수점 연산은 특별히 필요하지 않는 한 모두 피하는 것이 좋습니다.부동소수점 수학에는 여러 가지 까다로운 에지 사례가 있으며, 주의를 기울이지 않으면 버그가 발생하는 경향이 있습니다.또한 하드웨어 FPU가 없는 소규모/저전력 장치에서는 계산 비용이 많이 들 수 있습니다.


◦이 답변의 이전 버전에서 ceildiv는 다음과 같이 구현되었습니다.return -(-a // b)로 변경되었습니다.return -(a // -b)논평가들이 후자가 벤치마크에서 약간 더 나은 성과를 낸다고 보고한 후.일반적으로 배당금(a)이 배당금(b)보다 크기 때문에 타당합니다.Python은 임의의 정밀도 산술을 사용하여 이러한 계산을 수행하기 때문에 단항 부정을 계산합니다.-a거의 항상 컴퓨팅보다 동등하거나 더 많은 작업이 필요합니다.-b.

천장으로 나누는 연산자가 없습니다.당신은 해야 합니다.import math및 사용math.ceil

솔루션 1: 부정이 있는 바닥에서 천장으로 변환

def ceiling_division(n, d):
    return -(n // -d)

Penn & Teller 공중부양 트릭을 연상시키는 이것은 "세상을 (부정으로) 뒤집고, (천장과 바닥이 바뀐) 평범한 바닥 분할을 사용하고, 그리고 나서 (부정으로) 세상을 (다시) 오른쪽으로 돌립니다."

솔루션 2: divmod()가 작업을 수행하도록 합니다.

def ceiling_division(n, d):
    q, r = divmod(n, d)
    return q + bool(r)

divmod() 함수는 다음을 제공합니다.(a // b, a % b)정수의 경우(반올림 오차로 인해 부동 소수점이 있는 경우에는 신뢰성이 떨어질 수 있습니다.의 단계bool(r)0이 아닌 나머지가 있을 때마다 지수에 1을 추가합니다.

해결책 3: 나눗셈 전에 분자를 조정

def ceiling_division(n, d):
    return (n + d - 1) // d

분자를 위쪽으로 변환하여 바닥 분할이 의도된 천장까지 반올림되도록 합니다.이것은 정수에 대해서만 사용할 수 있습니다.

솔루션 4: math.ceil()을 사용하도록 floats로 변환합니다.

def ceiling_division(n, d):
    return math.ceil(n / d)

math.ceil() 코드는 이해하기 쉽지만 int에서 float로 변환하고 다시 변환합니다.이것은 매우 빠르지 않고 반올림 문제가 있을 수 있습니다.또한 "참 나눗셈"이 플로트를 생성하고 ceil() 함수가 정수를 반환하는 Python 3 의미론에 의존합니다.

은 할 수 .(x + (d-1)) // d을 나눌 때.x타고d를 들어, 예를 들어, 기호입니다.(x + 4) // 5.

항상 인라인으로도 할 수 있습니다.

((foo - 1) // bar) + 1

python3에서 이것은 속도에 관심이 있다면 플로트 분할과 호출 천장()을 강제하는 것보다 더 빠른 규모의 순서에 불과합니다.사용법을 통해 필요하다는 것을 증명하지 않는 한 그렇게 해서는 안 됩니다.

>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000)
1.7249219375662506
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000)
12.096064013894647

math.ceil은 53비트의 정밀도로 제한됩니다.큰 정수를 사용하는 경우 정확한 결과를 얻지 못할 수 있습니다.

gmpy2 라이브러리는 다음을 제공합니다.c_div천장 반올림을 사용하는 함수.

고지 사항:나는 gmpy2를 유지합니다.

사용할 수 있습니다.-(-a//b)또는math.ceil(a/b)math천장 분할용

숫자를 여러 개까지 셀링하려면 다음과 같이 하십시오.우리가 엑셀에서 수학 셀링을 하는 것처럼 작동합니다.

def excel_celling(number=None, multiple_off=None):
    quotient = number // multiple_off
    reminder = number % multiple_off
    celling_value = quotient * multiple_off + (multiple_off, 0)[reminder==0]
    return int(celling_value)


assert excel_celling(99.99, 100) == 100, "True"
print(excel_celling(99.99, 100) , 100)
assert excel_celling(1, 100) == 100, "True"
print(excel_celling(1, 100),100)
assert excel_celling(99, 100) == 100, "True"
print(excel_celling(99, 100),100)
assert excel_celling(90, 100) == 100, "True"
print(excel_celling(90, 100),100)
assert excel_celling(101, 100) == 200, "True"
print(excel_celling(101, 100),200)
assert excel_celling(199, 100) == 200, "True"
print(excel_celling(199, 100),200)
assert excel_celling(199.99, 100) == 200, "True"
print(excel_celling(199.99, 100),200)
assert excel_celling(200, 100) == 200, "True"
print(excel_celling(200, 100),200)

결과.

100 100

100 100

100 100

100 100

200 200

200 200

200 200

200 200

간단한 해결책: a // b + 1

언급URL : https://stackoverflow.com/questions/14822184/is-there-a-ceiling-equivalent-of-operator-in-python