C 프로그램에서 나는 아래 작업을 시도하고 있었다 (동작을 확인하기 위해)
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
(2, -2 , -2)
gcc에서 와 같이 출력을주었습니다 . 나는 매번 긍정적 인 결과를 기대하고있었습니다. 계수가 음수 일 수 있습니까? 아무도이 행동을 설명 할 수 있습니까?
답변
C99 는 다음과 같이 표현할 수 있어야 합니다 a/b
.
(a/b) * b
+ a%b
는 같을 것이다a
논리적으로 말이됩니다. 권리?
이것이 무엇으로 연결되는지 봅시다 :
예 A. 5/(-3)
는-1
=> (-1) * (-3)
+ 5%(-3)
=5
5%(-3)
2 인 경우에만 발생할 수 있습니다 .
예 B. (-5)/3
는-1
=> (-1) * 3
+ (-5)%3
=-5
경우에만 발생할 수 (-5)%3
있다-2
답변
%
C 의 연산자는 모듈로 연산자가 아니라 나머지 연산자입니다.
모듈로 및 나머지 연산자는 음수 값이 다릅니다.
나머지 연산자의 경우 결과의 부호는 피제수의 부호와 같지만 모듈러스 연산자의 경우 결과의 부호는 제수와 같습니다.
C는 다음 과 같이 %
작업을 정의합니다 a % b
.
a == (a / b * b) + a % b
를 /
향해 정수 나누기를 사용 0
합니다. 그것은 모듈로 연산자가 아닌 나머지 연산자로 0
정의하는 (음의 무한대가 아닌)쪽으로 수행되는 잘림입니다 %
.
답변
C99 사양을 기반으로 : a == (a / b) * b + a % b
계산할 함수를 작성할 수 있습니다 (a % b) == a - (a / b) * b
!
int remainder(int a, int b)
{
return a - (a / b) * b;
}
모듈로 연산의 경우 다음과 같은 기능을 가질 수 있습니다 (가정 b > 0
)
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}
내 결론은 a % b
C에서 나머지 연산이며 모듈로 연산 이 아니라는 것 입니다.
답변
나는 숫자가 음수인지 확인할 필요가 없다고 생각합니다.
포지티브 모듈로를 찾는 간단한 함수는 다음과 같습니다.
편집 : 가정 N > 0
및N + N - 1 <= INT_MAX
int modulo(int x,int N){
return (x % N + N) %N;
}
이것은 x의 양수 값 과 음수 값 모두에 적용 됩니다 .
원래 추신 : 또한 @chux가 가리키는 아웃으로, 귀하의 x와 N은 대체 각각 INT_MAX-1 및 INT_MAX 같은 도달 할 수있는 경우 int
에 long long int
.
그리고 그들이 오랫동안 긴 한계를 넘어 서면 (즉, LLONG_MAX 근처), 당신은 여기에 다른 답변에서 설명 된 것처럼 긍정적이고 부정적인 경우를 별도로 처리해야합니다.
답변
다른 답변은 C99 이상 에서 설명 했으므로 음의 피연산자를 포함하는 정수 나누기는 항상 0으로 잘립니다 .
C89에서 , 결과가 상향 또는 하향으로 반올림되는지는 구현-정의 됨에 유의한다 . 모든 표준에서 (a/b) * b + a%b
동일 하기 때문에 음의 피연산자가 포함 a
된 결과 %
도 C89에 구현 정의되어 있습니다.
답변
계수가 음수 일 수 있습니까?
%
Euclidean_division 이후 가 아니라 나머지 연산자 인 나머지 나눗셈이므로 음수 일 수 있습니다 . C99이므로 결과는 0, 음수 또는 양수일 수 있습니다.
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
모듈로 원 영업 이익은 고전적인 유클리드 모듈로 하지 %
.
나는 매번 긍정적 인 결과를 기대하고있었습니다.
때마다 잘 정의 된 유클리드 모듈로 수행하려면 a/b
정의를, a,b
어떤 부호이며, 결과는 부정적인 결코 :
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
modulo_Euclidean( 7, 3) --> 1
modulo_Euclidean( 7, -3) --> 1
modulo_Euclidean(-7, 3) --> 2
modulo_Euclidean(-7, -3) --> 2
답변
모듈로 연산의 결과는 분자의 부호에 따라 다르므로 y 와 z에 대해 -2를 얻습니다.
여기 참조입니다
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
정수 부서
이 섹션에서는 정수 나누기를 수행하는 기능에 대해 설명합니다. GNU C에서는 ‘/’연산자가 항상 0으로 반올림하기 때문에 이러한 함수는 GNU C 라이브러리에서 중복됩니다. 그러나 다른 C 구현에서 ‘/’는 음수 인수로 다르게 반올림 될 수 있습니다. div와 ldiv는 몫을 반올림하는 방법을 지정하기 때문에 유용합니다. 나머지는 분자와 같은 부호를 갖습니다.