파이썬의 math.ceil () 및 math.floor () 연산이 정수 대신 부동 소수점을 반환하는 이유는 무엇입니까?


170

누군가 이것을 설명 할 수 있습니까 ( 문서와 직선 -강조 광산).

math.ceil (x) x의 상한값 을 x 보다 크거나 같은 가장 작은 정수 값인 float로 반환합니다 .

math.floor (x) x 의 플로어를 x 보다 작거나 같은 가장 큰 정수 값인 float로 반환합니다 .

왜 것 .ceil그리고 .floor그들은 정의에 의해 계산 정수로 가정된다 반환 수레 때?


편집하다:

그럼이 그들이 이유에 아주 좋은 인수를 가지고 있어야 수레를 반환 할 때, 그리고 난 그냥, 생각에 익숙해되었다 @jcollado은 그들이 실제로 지적 파이썬 3에서 반환하는 int를 ...


1
내 생각에 그것은 x가 정수가 아닌 float이기 때문에 파이썬을 모르거나 사용하기 때문에 다른 사람이 더 명확하게 대답하도록 할 것입니다. :)
Adam V

6
@ Adam- 그러나 ceil / floor 연산의 요점은 float를 정수로 반올림하는 것입니다!
Yarin

1
이것은 내가 잘못 왔기 때문에 처음 만났을 때 나를 자극했습니다. 적어도 사용하기가 어렵지 않습니다 int(floor(n)).
wim

1
아이러니하게도 (플로트가 오버플로를 방지하기 위해 사용 되었기 때문에) 플로어 표현으로 인해 floor / ceil에 의해 반환되는 값은 64 비트 int가 오버플로되기 훨씬 전에 플로트 표현으로 인해 낮은 자리수에서 의미가 없습니다. [이것은 32 비트의 옛날에는 사실이 아니 었습니다.]
Yves Daoust

답변:


99

부동 소수점 숫자의 범위는 일반적으로 정수 범위를 초과합니다. 부동 소수점 값을 반환함으로써 함수는 표현 가능한 정수 범위를 벗어난 입력 값에 대한 합리적인 값을 반환 할 수 있습니다.

고려 : floor()정수를 반환하면 무엇을 floor(1.0e30)반환 해야 합니까?

이제 파이썬의 정수는 이제 임의의 정밀도이지만 항상 그런 것은 아닙니다. 표준 라이브러리 함수는 동등한 C 라이브러리 함수를 둘러싼 얇은 래퍼입니다.


13
그리고 파이썬 정수는 이제 임의의 정밀도이지만, 바닥과 천장을 정수로 표현할 수없는 수레가 여전히 있습니다. floor(float("inf"))또는을 시도하십시오 ceil(float("nan")).
Michael Hoffman

4
@ Michael- 분명히 P3에서 시도하면 오버플로 예외가 발생합니다. 참조 jcollado 의 대답
Yarin

4
어, 'long'유형 (일명 'bigint')을 반환해야합니까? 나에게 명백한 대답처럼 보이지만 이제는 어떻게 든 순진한 느낌이 든다.
koschei

3
@ koschei : Python 3.x에서 수행됩니다 .jcollado의 답변을 참조하십시오.
Greg Hewgill

또한 범위 내에있는 숫자에도 이것이 왜 의미가 있는지 다른 대답에 대한 주석을 참조하십시오 .
ivan_pozdeev

96

다른 답변에서 지적했듯이 파이썬에서는 오버플로 문제를 방지하는 역사적인 이유로 인해 부동 소수점을 반환합니다. 그러나 파이썬 3에서는 정수를 반환합니다.

>>> import math
>>> type(math.floor(3.1))
<class 'int'>
>>> type(math.ceil(3.1))
<class 'int'>

PEP 3141 에서 자세한 정보를 찾을 수 있습니다 .


@ jcollado- P3에서 정수를 반환하는 곳은 어디입니까?
Yarin

4
@ Yarin 방금 위의 명령을 입력했습니다. float("inf")또는로 시도 float("nan")하면 OverflowError예외 가 발생합니다.
jcollado

10
완벽을 기하기 위해 파이썬 numpy.floorceil리턴 플로트 (<class 'numpy.float64'>)
Neil G

1
@jcollado : float("inf")Python 2.7 또는 3에서 예외를 생성하지 않음
endolith

1
@endolith 당신이 맞아요, 나는 그것을 확인했고 더 이상 발생하지 않습니다. 아마도 이것은 2011 년 12 월 이후로 변경된 것입니다.
jcollado

18

귀하의 의견에 혼란의 근원이 분명합니다.

ceil / floor 연산의 요점은 float를 정수로 변환하는 것입니다!

천장 및 바닥 작업의 요점은 부동 소수점 데이터를 정수 값 으로 반올림하는 것 입니다. 형식 변환을하지 마십시오. 정수 값 을 가져야하는 사용자 는 작업 후에 명시 적 변환을 수행 할 수 있습니다.

사용 가능한 모든 것이 정수를 리턴하는 ceil 또는 float 연산이면 사소한 정수로 반올림 값을 구현할 수 없습니다. 먼저 입력이 표현 가능한 정수 범위 내에 있는지 확인한 다음 함수를 호출해야합니다. 별도의 코드 경로에서 NaN 및 무한대를 처리해야합니다.

또한 IEEE 754 를 준수하려면 부동 소수점 숫자를 반환하는 ceil 및 floor 버전이 있어야합니다 .


스티븐-나는 내 의견을 다시 썼다. 그러나 그것은 내 혼란의 원천이 아닙니다. 오히려 범위 차이를 인식하지 못하고있었습니다.
Yarin

슬프게도, 오늘 투표가 없습니다. 이것은 표현의 제한보다 훨씬 더 정답입니다.
Marcin

13
수년간의 프로그래밍에서 필자는 바닥 / 천장의 결과가 정수 대신 부동 소수점이 되기를 원했던 상황을 떠올리지 않았습니다 . python3 정수를 반환한다는 사실은 이것이 실제로 더 유용한 일임을 보여줍니다. 나는 "..."주장을 사지 않습니다. 프로그래머가 원하는 것이 아니라 행동에 따라 요점을 정의하는 것 같습니다.
ShreevatsaR

2
@ShreevatsaR 나는 그 상황을 몇 번 겪었습니다 (그러나 주로 Python 컨텍스트 외부). 내가 기억하는 시간은 Mandelbrot 세트로 작업 할 때입니다. 때로는 정수 값을 만들어야하지만 그 직후에 값에 일부 부동 소수점 연산을 적용합니다 (예 : 0.5로 스케일링). 그런 다음 플로팅 플로트를 유지하고 부동 소수점 연산을 먼저 int로 변환 한 다음 즉시 다시 플로팅으로 변환하는 것보다 훨씬 효율적입니다.
blubberdiblub

17

파이썬의 수학 라이브러리는 float를 반환하는 C 수학 라이브러리 주위의 얇은 래퍼이기 때문에.


C 수학 라이브러리는 임의의 정밀 정수를 지원합니까? 그것이 다른 파이썬 수학 함수가 반환하는 것이기 때문입니다.
endolith

5

Python 2.4 이전에는 정수가 잘린 실수의 전체 범위를 보유 할 수 없었습니다.

http://docs.python.org/whatsnew/2.4.html#pep-237-unifying-long-integers-and-integers


2
"절단 된 실수의 전체 범위"를 보유 할 수는 없습니다. 이는 분명히 무한 세트이므로 무한한 양의 메모리가 필요하기 때문입니다. 잘린 수레 의 범위를 보유 할 수 있으며 which의 작은 하위 집합입니다.
leftaroundabout

6
@leftaroundabout-까다로운 까다로운! 당신은 내가 무슨 뜻인지 알았습니다.
Mark Ransom

4

float의 범위가 정수의 범위보다 크기 때문에 정수를 반환하면 오버플로가 발생할 수 있습니다


7
정수는 파이썬에서 넘치지 않습니다. 정수가 너무 커지면 bigint로 변환됩니다. 파이썬 인터프리터를 열고 "2 ** 500"을 입력하면 int처럼 모든 방식으로 취급 할 수있는 객체를 얻게됩니다.
koschei

@ koschei : 무한대를 나타내려고 할 때 bigints도 오버플로됩니다.
Stephen Canon

4

이것은 매우 흥미로운 질문입니다! 부동 소수점은 지수 (= bits_for_exponent) 를 저장하기 위해 약간의 비트가 필요하므로 2**(float_size - bits_for_exponent)항상 정수 값 보다 큰 부동 소수점 숫자 입니다! 다른 극단적 인 경우 음의 지수를 가진 float는 다음 중 하나를 제공합니다 1.0 또는 -1. 이 논의하게 정수 범위플로트 범위 이러한 기능은 단순히 숫자가 외부 정수 유형의 범위 때마다 원래의 수를 반환하기 때문에 논쟁을. 파이썬 함수는 함수의 래퍼 C이므로 실제로 C정수를 반환하고 프로그래머가 ceil / floor를 호출하기 전에 범위 / NaN/ Inf검사 를 수행 해야하는 함수 의 결함입니다 .

따라서 논리적 인 대답은 이러한 함수가 유용 할 때 유일하게 정수 범위 내의 값을 반환하므로 부동 소수점을 반환한다는 사실은 실수 이며 이것을 실현하는 데 매우 똑똑합니다!


1

다른 언어도이 작업을 수행하기 때문에 일반적으로 허용되는 동작입니다. (다른 답변에서 볼 수 있듯이 좋은 이유로)


또는 찰스가 말한 것. :)
Almo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.