정수 나누기의 동작은 무엇입니까?


209

예를 들어

int result;

result = 125/100;

또는

result = 43/100;

결과는 항상 부서의 바닥입니까? 정의 된 동작은 무엇입니까?


5
요약 : 부호있는 정수 나누기는 0으로 잘립니다 . 음수가 아닌 결과의 경우 이는 바닥과 같습니다 (-Infinity 방향으로 반올림). (C89가 이것을 보증하지는 않습니다. 답을보십시오.)
Peter Cordes

5
코드가 어떤 기술을 사용할 것인지에 대한 의도적 인 결정을 내리는 것처럼 누구나 "제로쪽으로 자르다"또는 "천장"또는 "바닥"이라고 말합니다. 코드가 말할 수 있다면"I just throw the dam fraction part in the trash and move on with life"
Timothy LJ Stewart

3
@ TimothyL.J.Stewart "코드"는 신중한 결정을 내립니다. 본 명세서에 따르면, 정수 분할은 T (runcation)-분할을 의미한다. 이 때문에 modulo / remainder 연산자는 다른 언어 (예 : Python 또는 Ruby)의 언어와 다르게 영향을받습니다. 참조 언어는 모듈로 연산자를 할 다른 방법의 목록을 위해 프로그래밍 언어를 일반적인 방법으로 최소 5 밖으로리스트 사업부 / 모듈로하기로 결정 것을 종이.
13steinj

1
@ 13steinj 나는 "제로쪽으로 잘린다 ... 바닥이 없다. 그 천장이 음수이면 ..."때로는 인간의 기억으로 미래에 기술이 전파되지 않는 의견으로 구어체 적으로 말하고있다 우리가 원하는 것처럼 "분수 부분이 던져졌다"는 것을 직관적으로 알면 기술 요점을 도출 할 수 있습니다. 기술은 큰 부담이지만 직관력은 가볍고 바람처럼 상쾌합니다. 나는 넓고 넓게 옮길 것이며 필요할 때 어디에서 시작해야하는지 알게 될 것입니다. 당신이 연결 한 종이처럼 감사합니다.
Timothy LJ Stewart

I 대답 여기 유클리드 분할 (정수 나눗셈과 계수 운영자 간의 상호 재생)에 중점을두고.
Picaud Vincent

답변:


182

결과는 항상 부서의 바닥입니까? 정의 된 동작은 무엇입니까?

예, 두 피연산자의 정수 몫입니다.

6.5.5 곱하기 연산자

6 정수를 나누면 / 연산자의 결과는 분수 부분을 버린 대수 몫입니다. 88) 몫 a / b가 표현 가능하면, 식 (a / b) * b + a % b는 a와 같아야한다.

그리고 해당 주석 :

88) 이것을``0으로 자르기 ''라고합니다.

물론 주목해야 할 두 가지 사항은 다음과 같습니다.

3 일반적인 산술 변환은 피연산자에서 수행됩니다.

과:

5 / 연산자의 결과는 첫 번째 피연산자를 두 번째 피연산자로 나눈 몫입니다. % 연산자의 결과는 나머지입니다. 두 연산에서 두 번째 피연산자의 값이 0이면 동작이 정의되지 않습니다.

[참고 : 강조 광산]


26
... 물론, 음수를 양수 (또는 vv)로 나누지 않는 한,이 값은 천장이됩니다.
Will A

74
그것은 바닥이나 천장이 아니며 분수 부분의 잘림이며 개념적으로 다릅니다!
lornova

38
@Will A : 아니요. 0을 향한 잘림으로 정의됩니다. 다른 것을 호출하면 혼란에 빠질 수 있으므로 그렇게하지 마십시오.
Martin York

44
적어도 수학적 관점에서 볼 때, 0을 향한 절단은 "> 0보다 크면 다른 천장"과 같습니다. 나는 그것을 잘라서 잘라내는 것이 바닥 / 천장이라고 부르는 것보다 간단하다고 생각하지만 둘 다 유효합니다. 그럼에도 불구하고 Will A의 요점은 유효합니다. Dirkgently의 대답은 부서의 결과에 대한 OP가 옳다고 말했기 때문에 부분적으로 잘못되었습니다.
브라이언

9
@Philip Potter : C89에 정의되어 있지 않으며 1998 C ++ 표준에 없다고 생각합니다. 이들에는 물론 (a / b) * b + a % b == a만족되는 한, 그리고 절대 값 a % b있었다 미만 수 a있지만 여부 a % b네거티브 부정적 a또는 b지정되지 않았다.
David Thornley

39

Dirkgently는 C99의 정수 나눗셈에 대한 훌륭한 설명 을 제공 하지만 C89에서는 음의 피연산자가있는 정수 나눗셈에 구현 정의 방향이 있음을 알아야합니다.

ANSI C 초안 (3.3.5)에서 :

피연산자가 음수 인 경우, / 연산자의 결과가 대수 지수보다 작은 최대 정수인지 또는 대수 지수보다 큰 최소 정수인지 여부는 % 연산자 결과의 부호와 같이 구현 정의됩니다. 몫 a / b가 표현 가능한 경우, 표현 (a / b) * b + a % b는 a와 같아야합니다.

따라서 C89 컴파일러가 붙어있을 때 음수로 조심하십시오.

FOR99가 그렇게했기 때문에 C99가 0으로 잘림을 선택했다는 것은 재미있는 사실입니다. comp.std.c 에서이 메시지 를 참조하십시오.


2
그리고 C99 초안 N1256 서문 단락 5는 reliable integer division새로운 언어 기능으로 언급 됩니다. 놀랍습니다 *-*.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

잘림은 가장 일반적인 CPU 하드웨어 (예 : x86)의 동작 방식이므로 다른 선택을하는 것은 미쳤습니다. IDK (Fortran 의미론 또는 하드웨어 동작)가 처음 등장했지만 IDK가 동일하다는 것은 우연이 아닙니다.
Peter Cordes

2
@PeterCordes : 가장 일반적인 CPU 하드웨어는 잘리는 분할보다 빠른 속도로 대부분의 상수로 분할을 수행 할 수 있습니다. 표준 그런 말을하는 IMHO, 그것은 더 좋았을 것 expr1 / expr2expr1 % expr2의 두 인스턴스 때 서로 일치해야합니다 expr1마찬가지로에 대해 동일한 방법으로 동일한 개체를 결합하고 expr2있지만, 바닥의 부문에 비해 절단의 선택은 달리 지정되지 않은 것입니다. 즉 많은 호환성을 깨지 않고 더 효율적인 코드 생성을 허용 한 것 (경 사진 경우 구현 고유의 동작을 문서화 수)
supercat

23

결과가 음수이면 C가 바닥이 아닌 0으로 잘립니다. 파이썬 정수 나누기가 왜 항상 여기에 있는지에 대한이 독서를 배웠습니다. 왜 파이썬의 정수 나누기 마루


3
나는 (neg % pos)가 부정적으로 진행되는 것이 유용한 지 궁금한 의견에 동의합니까? 관련 메모에서, "unsignedvar> signedvar"의 경우에 산술적으로 부정확 한 동작이 유용한 지 궁금합니다. 항상 올바른 행동을 요구하지 않는 근거를 이해할 수 있습니다. 잘못된 행동이 필요하다는 근거는 없습니다.
supercat

8
바닥이 정수 나눗셈에 대한 올바른 동작 인 이유에 대한 훌륭한 참조를 위해 +1 (C의 정의와는 달리 깨지지 않고 거의 사용되지 않음).
R .. GitHub 중지 지원 얼음

@supercat 고려 :의 filtered = (k - 1) * filtered + value + carry; carry = filtered % factor; filtered /= factor값을 변경하면서 반복했습니다 value. 시간 상수가있는 1 차 저역 통과 필터에 대한 근사한 근사치를 만듭니다 k...하지만 나누기가 잘리고 carry음수 값을 얻는 경우에만 대칭 입니다. 나눗셈에 대한 두 가지 행동은 때때로 편리합니다.
hobbs December

1
@ hobbs : 신호가 0을 넘을 때 위의 코드가 깨끗하게 작동한다고 생각하지 않습니다. 경우 div바닥의 나눗셈 연산자이고 factor홀수, 그때 filtered += (filter+(factor div 2)) div factor까지의 모든 값이 깨끗한 대칭 동작을 얻을 것이다 INT_MAX-(factor div 2).
supercat

@ supercat 그것은 작동하지만; 그 코드는 원자 시계 컨트롤러에서 잠시 동안 실행 한 것에서 약간 증류됩니다.
hobbs

21

예, 결과는 항상 0으로 잘립니다. 가장 작은 절대 값으로 반올림합니다.

-5 / 2 = -2
 5 / 2 =  2

부호없는 및 음이 아닌 부호있는 값의 경우 이는 바닥과 같습니다 (-Infinity로 반올림).


43
바닥이 아닌 잘림 .
dan04

9
@ dan04 : yep floor는 양의 정수에만 유효합니다 :)
Leonid

13

결과는 항상 부서의 바닥입니까?

아니요. 결과는 다양하지만 변동은 음수 값에 대해서만 발생합니다.

정의 된 동작은 무엇입니까?

정수 나누기가 0으로 반올림되는 동안 바닥이 음의 무한대로 명확하게 반올림되도록합니다 (잘라 내기)

양수 값은 동일합니다.

int integerDivisionResultPositive= 125/100;//= 1
double flooringResultPositive= floor(125.0/100.0);//=1.0

음수의 경우이 값이 다릅니다

int integerDivisionResultNegative= -125/100;//=-1
double flooringResultNegative= floor(-125.0/100.0);//=-2.0

0

나는 사람들이 귀하의 질문에 대답했지만 평신도 용어로 알고 있습니다.

5 / 2 = 2 // 5와 2는 모두 정수이므로 정수 나누기는 항상 소수를 자릅니다.

5.0 / 2 or 5 / 2.0 or 5.0 /2.0 = 2.5 // 여기서 5 또는 2 또는 둘 다에 소수점이 있으므로 몫은 10 진수입니다.

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