맨위로가기

모듈로

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

모듈로는 수학에서 동치류의 일종으로, 어떤 대표원으로도 선택될 수 있으며, 일반적으로는 유클리드 나눗셈의 나머지를 대표원으로 선택한다. 모듈로 연산은 거의 모든 컴퓨팅 시스템에서 사용되며, 프로그래밍 언어에 따라 연산 결과의 부호 처리 방식에 차이가 있다. 모듈로 연산은 암호학, 컴퓨터 과학 등 다양한 분야에 응용되며, 2의 거듭제곱으로 나눌 때 비트 연산을 사용하여 성능을 최적화할 수 있다. 모듈로 연산의 결과는 피제수의 부호에 따라 달라질 수 있으므로 주의해야 하며, 확장된 모듈로 연산도 존재한다.

더 읽어볼만한 페이지

  • 연산자 (프로그래밍) - 중위 표기법
    중위 표기법은 사람이 이해하기 쉬운 연산자 표기 방식이지만, 컴퓨터가 구문 분석하기 어렵고 연산 순서를 위해 괄호나 연산자 우선순위 규칙이 필요하다.
  • 연산자 (프로그래밍) - 형 변환
    형 변환은 프로그래밍에서 변수의 데이터 타입을 변경하는 것으로, 암시적 형 변환과 명시적 형 변환으로 나뉘며, 객체 지향 프로그래밍에서는 업캐스팅과 다운캐스팅이 발생하고, 각 언어는 고유한 규칙과 방법을 제공하며 잘못된 형 변환은 오류를 유발할 수 있다.
  • 모듈러 산술 - 이산 로그
    이산 로그는 유한군에서 이산 거듭제곱의 지수를 찾는 역함수로, 소수 p를 법으로 하는 정수 모듈러 곱셈 그룹에서 계산적으로 풀기 어려운 문제이며, 현대 암호 시스템의 안전성 기반이지만 양자 알고리즘으로 효율적 해결이 가능하여 양자 내성 암호 연구가 필요하다.
  • 모듈러 산술 - 중국인의 나머지 정리
    중국인의 나머지 정리는 여러 개의 연립 합동식의 해 존재성과 유일성에 대한 정리이며, 정수론, 대수학, 암호학 등 다양한 분야에 응용된다.
  • 컴퓨터 산술 - IEEE 754
    IEEE 754는 부동소수점 숫자를 표현하고 처리하기 위한 국제 표준으로, 다양한 형식과 연산, 반올림 규칙, 예외 처리 등을 정의한다.
  • 컴퓨터 산술 - 1의 보수
    1의 보수는 이진수에서 양수는 일반적인 이진수로, 음수는 양수의 각 비트를 반전시켜 표현하며, 덧셈 시 자리올림수가 발생하면 결과값에 더해야 하고, 0을 중복 표현하는 단점으로 현대에는 2의 보수가 주로 사용된다.
모듈로
모듈로 연산
유형이항 연산
기호mod
정의a mod n은 a를 n으로 나눈 나머지
예시
7 mod 43
5 mod 32
4 mod 20
3 mod 53
속성
분배 법칙(a + b) mod n = ((a mod n) + (b mod n)) mod n
(a * b) mod n = ((a mod n) * (b mod n)) mod n
항등원0 (덧셈에 대한 항등원)
역원덧셈에 대한 역원은 존재함 (모듈로 n 합동에 따라)
관련 연산
나눗셈a = (n * q) + (a mod n) (q는 몫)
합동a ≡ b (mod n) (a mod n = b mod n)
응용 분야
암호학RSA 암호 등
컴퓨터 과학해시 테이블, 의사 난수 생성기 등

2. 정의 및 표기법

수학에서 모듈로 연산은 기본적으로 나눗셈의 나머지를 구하는 연산이다. 수학적으로 모듈로 연산의 결과는 특정 정수들의 동치류를 나타내며, 이 동치류에 속하는 어떤 정수든 대표원으로 사용할 수 있다. 하지만 일반적으로는 해당 동치류에서 가장 작은 음이 아닌 정수인 '''최소 양의 나머지'''를 사용하는데, 이는 유클리드 나눗셈의 나머지와 같다.[2]

컴퓨터 과학이나 프로그래밍 언어에서는 모듈로 연산의 정의나 사용 방식이 수학적인 정의와 약간 다를 수 있다. 컴퓨터는 숫자를 표현하고 저장하는 방식이 다양하기 때문에, 특히 피제수(a)나 제수(n)가 음수일 때 나머지의 부호를 처리하는 방식이 구현 환경이나 언어마다 다를 수 있다. 대부분의 시스템에서 몫(q)과 나머지(r)는 a = nq + r 이고 |r| < |n| 이라는 기본 조건을 만족하지만, 나머지의 부호를 결정하는 데에는 여러 가지 규칙이 존재한다. 예를 들어 나머지가 피제수와 같은 부호를 갖도록 하는 '절단 나눗셈', 제수와 같은 부호를 갖도록 하는 '바닥 나눗셈', 항상 음수가 아니도록 하는 '유클리드 나눗셈' 등이 있다.[3][4][5] 어떤 규칙을 따르는지는 프로그래밍 언어의 설계나 표준에 따라 결정된다.

프로그래밍 언어에서는 모듈로 연산을 위해 다양한 표기법을 사용한다. 많은 언어에서 '%' 기호를 연산자로 사용하며('a % n'), 'mod' 또는 'Mod'와 같은 키워드나 함수 이름('a mod n', 'mod(a, n)')을 사용하기도 한다.

간단한 예로, 양의 정수 5를 2로 나눈 나머지는 1이므로 "5 mod 2"의 결과는 1이다. 9를 3으로 나눈 나머지는 0이므로 "9 mod 3"의 결과는 0이다.

모듈로 연산은 정수론의 합동 산술과 깊은 관련이 있다.

2. 1. 수학적 정의

수학에서 모듈로 연산은 나눗셈의 나머지를 구하는 연산이다. 엄밀히 말하면, 모듈로 연산의 결과는 특정 정수들의 동치류이며, 이 동치류에 속하는 어떤 정수든 대표원으로 사용할 수 있다. 하지만 일반적으로는 해당 동치류에서 가장 작은 음이 아닌 정수, 즉 유클리드 나눗셈의 나머지를 사용하며 이를 '''최소 양의 나머지'''라고 부른다.[2]

그러나 컴퓨터나 계산기는 숫자를 저장하고 표현하는 방식이 다양하기 때문에, 실제 프로그래밍 언어하드웨어에서는 모듈로 연산의 정의가 조금씩 다를 수 있다.

대부분의 컴퓨팅 시스템에서, 정수 a를 정수 n으로 나눈 q와 나머지 r은 다음 세 가지 조건을 만족한다.

\begin{align}

&q \in \mathbb{Z} \quad (\text{몫 } q\text{는 정수}) \\

&a = n q + r \quad (\text{원래 수 } a\text{는 몫과 제수의 곱에 나머지를 더한 값}) \\

&|r| < |n| \quad (\text{나머지 } r\text{의 절댓값은 제수 } n\text{의 절댓값보다 작음})

\end{align} (1)

이 정의에 따르면, 나머지가 0이 아닐 경우 부호에 대한 모호성이 생긴다. 예를 들어, -21을 5로 나누는 경우를 생각해보자.

  • -21 = 5 \times (-4) + (-1) : 몫은 -4, 나머지는 -1이다.
  • -21 = 5 \times (-5) + 4 : 몫은 -5, 나머지는 4이다.


두 경우 모두 위의 조건 (1)을 만족한다. (-14 모두 절댓값이 5보다 작다.) 정수론에서는 보통 양수인 나머지(여기서는 4)를 선택하지만, 컴퓨팅 환경에서는 프로그래밍 언어나 a 또는 n의 부호에 따라 다른 나머지를 선택할 수 있다. 예를 들어, 표준 파스칼이나 ALGOL 68은 제수 n이 음수라도 나머지는 항상 양수(또는 0)가 되도록 정의한다. 반면, C90 표준 이전의 C언어나 C++03 이전의 C++ 등 일부 언어에서는 an이 음수일 때 나머지의 부호를 명확히 규정하지 않고 구현 환경에 따라 달라지도록 허용했다.[65]

한편, a를 0으로 나누는 연산(a \pmod 0)은 대부분의 시스템에서 정의되지 않으며, 실행 시 0으로 나누기 오류를 발생시킬 수 있다. 일부 시스템에서는 이를 a로 정의하기도 한다.

피제수 a와 제수 n의 부호에 따라 나머지의 부호를 결정하는 방식에는 여러 가지 규칙이 있으며, 이는 몫 q를 어떻게 정의하느냐에 따라 달라진다. 주요 규칙들은 다음과 같다.

\right\rfloor || 항상 음수가 아님 (0 이상) || 레이먼드 T. 부테[4][67]

|-

|
반올림 나눗셈
'''반올림 나눗셈'''
(Rounding Division) || q = \operatorname{round}\left(\frac{a}{n}\right)
(가장 가까운 정수, 짝수 선호) || -\frac

다양한 나눗셈 규칙과 나머지 정의
규칙몫 (q) 정의나머지 (r) 부호 특징관련 인물/표준
절단 나눗셈
절단 나눗셈
(Truncated Division)
q = \operatorname{trunc}\left(\frac{a}{n}\right)
(0 방향으로 절삭)
피제수(a)와 같거나 0C99, C++11 등 다수
바닥 나눗셈
바닥 나눗셈
(Floored Division)
q = \left\lfloor\frac{a}{n}\right\rfloor
(음의 무한대 방향 내림)
제수(n)와 같거나 0도널드 크누스[3][66]
유클리드 나눗셈
유클리드 나눗셈
(Euclidean Division)
q = \sgn(n) \left\lfloor\frac{a}{\left>n\right|}
{2}와 \frac

{2} 사이
(0에 가까운 쪽) || Common Lisp, IEEE 754

|-

|
천장 나눗셈
'''천장 나눗셈'''
(Ceiling Division) || q = \left\lceil\frac{a}{n}\right\rceil
(양의 무한대 방향 올림) || 제수(n)와 반대이거나 0 || Common Lisp

|}

각 규칙에 따른 몫과 나머지의 관계는 식 (1) a = nq + r|r| < |n|을 항상 만족한다.

  • 절단 나눗셈: 몫은 a/n의 소수점 이하를 버려 0에 가깝게 만든다. 나머지는 원래 피제수 a와 같은 부호를 가진다. 예를 들어, -21 / 5 = -4.2이므로 q = \operatorname{trunc}(-4.2) = -4이고, r = -21 - 5 \times (-4) = -1이다.
  • 바닥 나눗셈: 몫은 a/n보다 작거나 같은 가장 큰 정수(음의 무한대 방향)이다. 나머지는 제수 n과 같은 부호를 가진다. 예를 들어, \lfloor -21 / 5 \rfloor = \lfloor -4.2 \rfloor = -5이므로 q = -5이고, r = -21 - 5 \times (-5) = 4이다.
  • 유클리드 나눗셈: 나머지가 항상 0 이상이 되도록 몫을 정의한다. 제수 n이 양수면 바닥 나눗셈과 같고, 음수면 q = \lceil a/n \rceil으로 계산하여 천장 나눗셈과 유사하게 동작한다. 결과적으로 나머지는 항상 0 \le r < |n|을 만족한다.
  • 반올림 나눗셈: 몫은 a/n에 가장 가까운 정수로 반올림한다. 나머지의 절댓값은 |n|/2 이하가 된다.
  • 천장 나눗셈: 몫은 a/n보다 크거나 같은 가장 작은 정수(양의 무한대 방향)이다. 나머지는 제수 n과 부호가 반대이거나 0이다.


피제수 a와 제수 n의 부호에 따라 어떤 규칙들이 동일한 결과를 내는지 살펴보면 다음과 같다.

  • a > 0, n > 0: 절단, 바닥, 유클리드 나눗셈 결과 동일.
  • a > 0, n < 0: 절단, 유클리드 나눗셈 결과 동일.
  • a < 0, n > 0: 바닥, 유클리드 나눗셈 결과 동일.
  • a < 0, n < 0: 절단, 바닥 나눗셈 결과 동일.


컴퓨터 과학자 단 레이젠(Daan Leijen)은 다음과 같이 평가했다.

: 부테는 유클리드 나눗셈이 규칙성과 유용한 수학적 속성 측면에서 다른 나눗셈보다 우수하다고 주장하며, 크누스가 옹호하는 바닥 나눗셈도 좋은 정의이다. 널리 사용됨에도 불구하고, 절단 나눗셈은 다른 정의보다 열등한 것으로 나타났다.[5][68]

유클리드 나눗셈과 바닥 나눗셈은 수학적으로 더 일관성이 있다는 평가를 받지만, 많은 프로그래밍 언어에서는 구현의 단순성 등의 이유로 절단 나눗셈 기반의 모듈로 연산을 채택하고 있다. 다만 절단 나눗셈은 ({-a})/b = {-(a/b)} = a/({-b})와 같은 부호 관련 항등식을 만족시킨다는 장점도 있다.[6]

결론적으로, 두 양의 정수 an에 대해 a '''modulo''' n (또는 a \pmod n)은 일반적으로 an으로 나눈 유클리드 나눗셈의 나머지를 의미한다. 예를 들어, 5를 2로 나누면 몫이 2이고 나머지가 1이므로 "5 mod 2"의 결과는 1이다. 9를 3으로 나누면 몫이 3이고 나머지가 0이므로 "9 mod 3"의 결과는 0이다.

a 또는 n이 음수인 경우, 모듈로 연산의 결과는 사용되는 나눗셈 규칙(절단, 바닥, 유클리드 등)에 따라 달라지며, 이는 프로그래밍 언어나 시스템마다 다를 수 있음을 유의해야 한다.

모듈로 연산은 정수론의 합동 산술과 밀접한 관련이 있다.

2. 2. 프로그래밍 언어에서의 표기법

수학에서 모듈로 연산의 결과는 하나의 동치류를 나타내지만, 컴퓨터 프로그래밍에서는 특정 대표값, 주로 유클리드 나눗셈의 나머지인 최소 양의 나머지를 사용한다.[2] 하지만 컴퓨터 시스템마다 숫자를 저장하고 표현하는 방식이 다르기 때문에, 모듈로 연산의 정확한 정의는 사용하는 프로그래밍 언어나 기본 하드웨어에 따라 달라질 수 있다.

거의 모든 컴퓨팅 시스템에서, ''a''를 ''n''으로 나눈 몫 ''q''와 나머지 ''r''은 다음 조건을 만족한다:

  • ''q''는 정수이다.
  • ''a'' = ''n'' ''q'' + ''r''
  • |''r''| < |''n''|


나머지 ''r''이 0이 아닐 경우, 부호에 대한 모호성이 생긴다. 양수 또는 음수의 두 가지 가능한 나머지가 존재하며, 이는 어떤 몫을 선택하는지에 따라 결정된다. 정수론에서는 보통 양의 나머지를 사용하지만, 프로그래밍 언어에서는 ''a'' 또는 ''n''의 부호에 따라 다르게 처리하는 경우가 많다. 예를 들어, 표준 파스칼이나 ALGOL 68은 음수 제수에 대해서도 양수 나머지를 반환하지만, C90과 같은 언어는 ''a''나 ''n''이 음수일 때의 동작을 특정하지 않고 구현에 맡기기도 했다.[65][10] ''a'' 모듈로 0은 대부분의 시스템에서 정의되지 않지만, 일부 시스템에서는 결과로 ''a''를 반환하기도 한다.

컴퓨터에서 모듈로 연산을 구현하는 방식에는 여러 가지 정의가 존재한다:

  • '''절단 나눗셈 (Truncated division)''': 몫 ''q''를 \operatorname{trunc}\left(\frac{a}{n}\right) (결과를 0 방향으로 절단)로 정의한다. 이 경우 나머지는 ''r'' = ''a'' - ''n'' ''q'' 이며, 피제수 ''a''와 같은 부호를 가진다. 많은 프로그래밍 언어(C99, C++11, Java 등)에서 '%' 연산자가 이 방식을 따른다.
  • '''바닥 나눗셈 (Floored division)''': 도널드 크누스가 제안한 방식으로, 몫 ''q''를 \left\lfloor\frac{a}{n}\right\rfloor (바닥 함수, 음의 무한대 방향으로 내림)로 정의한다.[3][66] 이 경우 나머지는 ''r'' = ''a'' - ''n'' ''q'' 이며, 제수 ''n''과 같은 부호를 가진다. Python, Ruby 등에서 사용된다.
  • '''유클리드 나눗셈 (Euclidean division)''': 레이먼드 T. 부테가 제안한 방식으로, 나머지가 항상 음수가 아니도록 (0 ≤ ''r'' < |''n''|) 정의한다.[4][67] Pascal (ISO 7185), Dart 등에서 사용된다.
  • '''반올림 나눗셈 (Rounding division)''': 몫 ''q''를 \operatorname{round}\left(\frac{a}{n}\right) (반올림, 가장 가까운 정수로)로 정의한다. 나머지는 -|''n''|/2 와 |''n''|/2 사이에 있다. Common Lisp, IEEE 754 표준 등에서 사용된다.
  • '''천장 나눗셈 (Ceiling division)''': 몫 ''q''를 \left\lceil\frac{a}{n}\right\rceil (천장 함수, 양의 무한대 방향으로 올림)로 정의한다. 나머지는 제수 ''n''과 부호가 반대이다. Common Lisp에서 지원한다.


Daan Leijen은 "부테는 유클리드 나눗셈이 규칙성과 유용한 수학적 속성 측면에서 다른 나눗셈보다 우수하다고 주장하며, 크누스가 옹호하는 바닥 나눗셈도 좋은 정의이다. 널리 사용됨에도 불구하고, 절단 나눗셈은 다른 정의보다 열등한 것으로 나타났다."라고 평가했다.[5][68] 하지만 절단 나눗셈은 ({-a})/b = {-(a/b)} = a/({-b}) 와 같은 항등식을 만족시킨다는 장점도 있다.[6]

많은 프로그래밍 언어는 모듈로 연산을 위한 연산자나 함수를 제공한다. 흔히 '%' (C, Java, Python 등), 'mod' (Pascal, Ada, MATLAB 등), 'rem' (Ada, Common Lisp 등)과 같은 이름이 사용된다. 일부 언어는 정수뿐만 아니라 부동소수점 수에 대해서도 모듈로 연산을 지원한다.

아래 표는 다양한 프로그래밍 언어에서 모듈로 연산을 어떻게 구현하는지 보여준다.

다양한 프로그래밍 언어의 모듈로 연산자/함수

3. 모듈로 연산의 성질

모듈로 연산은 덧셈, 뺄셈, 곱셈 등 다른 수학적 연산과 유사한 성질을 가지며, 이러한 성질은 암호학의 디피-헬만 키 교환 같은 분야에서 유용하게 활용된다. 일반적으로 모듈로 연산의 성질은 정수 ''a'', ''b'', ''n''에 대해 정의된다.


  • 항등원 (Identity)
  • * (''a'' mod ''n'') mod ''n'' = ''a'' mod ''n'' (멱등성)
  • * ''n''''x'' mod ''n'' = 0 (단, ''x''는 양의 정수)
  • * 만약 ''p''가 소수이고 ''b''의 약수가 아니라면, 페르마의 소정리에 따라 ''ab''''p''−1 mod ''p'' = ''a'' mod ''p'' 이다.

  • 역원 (Inverse)
  • * [(-''a'' mod ''n'') + (''a'' mod ''n'')] mod ''n'' = 0
  • * ''b''−1 mod ''n''은 모듈러 곱셈 역원을 나타낸다. 이 역원은 ''b''와 ''n''이 서로소일 경우에만 정의되며, 다음 식을 만족한다: [(''b''−1 mod ''n'')(''b'' mod ''n'')] mod ''n'' = 1

  • 분배 법칙 (Distributive)
  • * (''a'' + ''b'') mod ''n'' = [(''a'' mod ''n'') + (''b'' mod ''n'')] mod ''n''
  • * ''ab'' mod ''n'' = [(''a'' mod ''n'')(''b'' mod ''n'')] mod ''n''

  • 나눗셈 (Division)
  • * (''a'' / ''b'') mod ''n'' = [(''a'' mod ''n'')(''b''−1 mod ''n'')] mod ''n''
  • * 이 연산은 우변이 정의될 때, 즉 ''b''와 ''n''이 서로소일 때만 정의된다. 그렇지 않으면 정의되지 않는다.

  • 역 곱셈 (Inverse Multiplication)
  • * [(''ab'' mod ''n'')(''b''−1 mod ''n'')] mod ''n'' = ''a'' mod ''n'' (단, ''b''−1 mod ''n''이 정의될 때)

4. 모듈로 연산의 응용

모듈로 연산은 순수 수학 이론뿐만 아니라 다양한 실용적인 분야에서 폭넓게 활용된다. 특히 컴퓨터 과학의 여러 영역, 예를 들어 알고리즘 설계나 데이터 구조 구현 등에서 중요한 역할을 수행한다. 대표적인 응용 분야 중 하나는 암호학으로, 현대 암호 시스템의 기반을 이루는 핵심적인 수학적 도구로 사용된다. 이 외에도 오류 검출 부호, 해시 함수 등 다양한 기술적 문제 해결에 응용될 수 있다.

4. 1. 암호학

모듈로 연산은 여러 수학적 연산처럼 인수분해하거나 확장할 수 있는 속성을 가지고 있다. 이러한 속성들은 암호학 분야, 특히 디피-헬만 키 교환과 같은 알고리즘의 안전성을 증명하는 데 유용하게 사용된다. 암호학에서 중요하게 활용되는 모듈로 연산의 주요 속성은 다음과 같다.

  • 동일성(Idempotence):
  • `(a mod n) mod n = a mod n`
  • 양의 정수 `x`에 대해 `nx mod n = 0`
  • `n`이 소수이고 `b`의 약수가 아닐 때, 페르마의 소정리에 따라 `abn-1 mod n = a mod n` 이 성립한다.
  • 역원(Inverse):
  • 덧셈 역원: `((-a mod n) + (a mod n)) mod n = 0`
  • 곱셈 역원: `b-1 mod n`은 모듈러 곱셈 역원을 의미하며, `b`와 `n`이 서로소일 때만 정의된다. 이때 `((b-1 mod n) (b mod n)) mod n = 1` 이 성립한다. 곱셈 역원의 존재는 암호학에서 중요한 역할을 한다.
  • 분배 법칙(Distributivity):
  • `(a+b) mod n = ((a mod n) + (b mod n)) mod n`
  • `ab mod n = ((a mod n) (b mod n)) mod n`
  • 나눗셈(Division): 모듈러 곱셈 역원을 이용하여 정의된다. `b`와 `n`이 서로소일 때, `(a/b) mod n = ((a mod n)(b-1 mod n)) mod n` 으로 계산할 수 있다.


이러한 모듈로 연산의 대수적 속성들은 암호화 및 복호화 과정을 수학적으로 안전하게 설계하는 기반을 제공한다.

5. 성능 문제 및 최적화

모듈로 연산은 기본적으로 나눗셈을 수행하여 나머지를 얻는 방식으로 구현되기 때문에 연산 시간이 소요될 수 있다. 하지만 특정 조건에서는 더 빠른 계산 방법이 존재한다.

예를 들어, 제수가 2의 거듭제곱인 경우 비트 연산을 이용하여 계산 속도를 높일 수 있으며[7][69], 컴파일러 최적화 기술을 통해 이러한 연산을 자동으로 더 효율적인 코드로 변환하기도 한다. 이러한 최적화 기법들은 각각의 하위 섹션에서 더 자세히 다룬다.

일반적인 상수로 나누는 모듈로 연산의 경우에도 상수-제수 최적화와 같은 기법을 사용하여 성능을 개선할 수 있다.

만약 사용 환경에서 모듈로 함수나 연산자가 제공되지 않거나 제대로 작동하지 않는 경우, 다음과 같은 수식을 이용하여 모듈로 연산을 구현할 수 있다. 여기서 `int()` 함수는 실수의 소수점 이하를 버리는 버림 함수이다.

`a - (n * int(a / n))`

5. 1. 비트 연산을 이용한 최적화

모듈로 연산은 일반적으로 나눗셈을 수행하고 나머지를 구하는 방식으로 구현된다. 그러나 특정 조건에서는 하드웨어 수준에서 더 빠르게 계산할 수 있는 방법이 존재한다. 예를 들어, 수의 내부 표현으로 2진법을 사용하는 컴퓨터에서는 제수가 2의 거듭제곱인 경우, 비트 연산 중 하나인 AND 연산을 이용하여 모듈로 연산을 대체할 수 있다. ''x''가 양의 정수라고 가정하거나, 특정 정의를 사용하면 다음과 같은 식이 성립한다:

`x % 2n == x & (2n - 1)`

구체적인 예는 다음과 같다 (''x''는 양의 정수):

  • `x % 2 == x & 1`
  • `x % 4 == x & 3`
  • `x % 8 == x & 7`


이러한 변환은 모듈로 연산보다 비트 연산을 더 효율적으로 처리하는 장치나 소프트웨어에서 계산 속도를 향상시킬 수 있다.[7][69]

컴파일러 최적화 기술이 발전함에 따라, 많은 컴파일러는 제수가 2의 거듭제곱인 상수인 `표현식 % 상수` 형태의 코드를 자동으로 인식하여 `표현식 & (상수-1)`과 같은 비트 연산 코드로 변환해준다. 덕분에 프로그래머는 성능 저하 없이 가독성이 좋은 코드를 작성할 수 있다.

하지만 이 최적화는 주의가 필요하다. C와 같이 모듈로 연산 결과의 부호가 피제수(나뉨수)의 부호를 따르는 언어에서는, 피제수가 음수일 경우 문제가 발생할 수 있다. 모듈로 연산 결과는 음수가 되지만, `표현식 & (상수-1)`의 결과는 항상 양수이기 때문이다. 따라서 이러한 언어에서 부호 있는 정수를 다룰 때는, 피제수가 음수인 경우를 고려하여 다음과 같이 비트 OR, NOT, AND 연산을 조합한 등가식을 사용해야 한다:

`x < 0 ? x | ~(2n - 1) : x & (2n - 1)`

일반적인 상수로 나누는 모듈로 연산에 대한 최적화는 상수-제수 최적화 기법을 사용하여 나눗셈을 먼저 계산하는 방식으로도 존재한다.

5. 2. 컴파일러 최적화

컴파일러는 특정 조건에서 모듈로 연산을 더 빠른 연산으로 대체하는 최적화를 수행할 수 있다. 특히 2의 거듭제곱 수로 나누는 모듈로 연산은 비트 AND 연산으로 효율적으로 변환될 수 있다. x가 양의 정수라고 가정하면, 이 관계식은 다음과 같다.

x % 2n == x & (2n - 1)

예시는 다음과 같다.

  • x % 2 == x & 1
  • x % 4 == x & 3
  • x % 8 == x & 7


컴퓨터하드웨어소프트웨어 환경에 따라 나머지 연산을 포함한 나눗셈보다 비트 연산이 훨씬 효율적으로 처리될 수 있으므로, 이 변환을 통해 계산 속도를 높일 수 있다.[7][69]

최적화 컴파일러는 소스 코드에서 표현식 % 상수 형태의 연산을 인식하고, 상수가 2의 거듭제곱일 경우 자동으로 표현식 & (상수-1) 형태로 변환한다. 이를 통해 프로그래머는 성능 저하 없이 가독성이 좋은 코드를 작성할 수 있다.

하지만 이 간단한 최적화는 나머지 연산 결과의 부호가 피제수(나누어지는 수)의 부호를 따르는 언어(예: C)에서는 그대로 적용할 수 없다. 피제수가 음수일 때 나머지 연산 결과는 음수가 될 수 있지만, 표현식 & (상수-1)의 결과는 항상 양수이기 때문이다. 따라서 피제수가 부호 있는 정수이고 음수일 가능성이 있다면, 이 최적화는 주의해서 적용해야 한다. 피제수가 음수일 수 있는 경우, 비트 OR, NOT, AND 연산을 사용하여 다음과 같이 동등한 표현식을 사용해야 한다.

x % 2n == x < 0 ? x | ~(2n - 1) : x & (2n - 1)

2의 거듭제곱이 아닌 일반 상수에 대한 모듈로 연산 최적화는 상수 나눗셈 최적화 기법을 통해 나눗셈을 먼저 계산하는 방식으로 이루어진다.

5. 3. 기타 최적화 기법

모듈로 연산은 일반적으로 나눗셈을 수행하고 그 나머지를 구하는 방식으로 계산된다. 하지만 특정 상황에서는 더 효율적인 계산 방법이 존재한다. 예를 들어, 2의 거듭제곱을 이용한 모듈로 연산은 비트 연산 중 하나인 AND 연산으로 대체할 수 있다. ''x''가 양의 정수라고 가정하면 다음과 같이 표현할 수 있다.

x % 2n == x & (2n - 1)

구체적인 예시는 다음과 같다.

x % 2 == x & 1

x % 4 == x & 3

x % 8 == x & 7

이러한 방식은 비트 연산이 모듈로 연산보다 하드웨어나 소프트웨어적으로 더 빠르게 처리될 수 있는 환경에서 계산 속도를 향상시키는 데 유용하다.[7]

컴파일러 최적화 기술 중에는 표현식 % 상수와 같이 상수로 모듈로 연산을 수행하는 코드를 분석하여, 만약 해당 상수가 2의 거듭제곱 형태라면 자동으로 표현식 & (상수-1) 형태로 변환하는 기능이 있다. 이를 통해 프로그래머는 성능 저하에 대한 걱정 없이 가독성이 좋은 코드를 작성할 수 있다.

하지만 이 최적화는 모듈로 연산의 결과가 나누어지는 수(피제수)의 부호를 따르는 언어(예: C)에서 피제수가 부호 있는 정수일 경우 주의가 필요하다. 피제수가 음수일 때 모듈로 연산 결과는 음수가 되지만, 표현식 & (상수-1)의 결과는 항상 양수이기 때문이다. 이런 언어에서는 x % 2n == x < 0 ? x | ~(2n - 1) : x & (2n - 1) 와 같이 비트 OR, NOT, AND 연산을 조합하여 동일한 결과를 얻도록 구현해야 한다.

일반적으로 상수를 이용한 모듈로 연산은 상수-제수 최적화 기법을 활용하여 먼저 나눗셈을 계산하는 방식으로 최적화되기도 한다.

6. 주의할 점

모듈로 연산의 결과는 사용하는 프로그래밍 언어하드웨어의 구현 방식에 따라 달라질 수 있다. 특히, 나머지의 부호가 피제수(나누어지는 수)의 부호를 따르도록 정의된 경우(예: C90과 같은 일부 프로그래밍 언어, '절단 나눗셈' 방식[5]) 예상치 못한 실수를 유발할 수 있으므로 주의해야 한다.

예를 들어, 어떤 정수가 홀수인지 확인하기 위해 2로 나눈 나머지가 1인지 검사하는 방법을 떠올리기 쉽다. C++ 코드로 나타내면 다음과 같다.

```cpp

// 잘못된 홀수 판별 함수 예시

bool is_odd(int n) {

return n % 2 == 1; // n을 2로 나눈 나머지가 1인지 확인

}

```

하지만 만약 해당 프로그래밍 환경에서 모듈로 연산의 나머지가 피제수의 부호를 따른다면, 이 코드는 `n`이 음수인 홀수일 때 잘못된 결과를 반환한다. 예를 들어 `n`이 -3이라면, `-3 % 2`의 결과는 1이 아니라 -1이 될 수 있다.[6] 이 경우, 위 함수는 `false`를 반환하게 되어, 음수 홀수를 짝수로 잘못 판단하는 오류가 발생한다.

이 문제를 해결하는 올바른 방법 중 하나는 나머지가 0이 아닌지를 확인하는 것이다. 나머지가 0이면 짝수이고, 0이 아니면 홀수이다. 0은 부호가 없기 때문에 이 방식은 피제수의 부호에 영향을 받지 않는다.

```cpp

// 올바른 홀수 판별 함수 예시 (방법 1)

bool is_odd(int n) {

return n % 2 != 0; // n을 2로 나눈 나머지가 0이 아닌지 확인

}

```

또 다른 대안은 비트 연산을 사용하는 것이다. 컴퓨터 내부에서 정수이진법으로 표현되며, 홀수는 항상 가장 마지막 비트(최하위 비트)가 1이라는 특징을 가진다. 따라서 비트 AND 연산자 `&`를 사용하여 마지막 비트가 1인지 확인하면 홀수 여부를 판별할 수 있다. 이 방법은 종종 모듈로 연산보다 더 효율적이다.

```cpp

// 올바른 홀수 판별 함수 예시 (방법 2: 비트 연산)

bool is_odd(int n) {

return n & 1; // n의 마지막 비트가 1인지 확인

}

```

물론, 나머지가 1 또는 -1인지를 직접 비교하는 방법도 가능하지만, 코드가 불필요하게 길어지고 연산 효율성 측면에서도 좋지 않다.

```cpp

// 비효율적인 홀수 판별 함수 예시

bool is_odd(int n) {

return n % 2 == 1 || n % 2 == -1; // 나머지가 1 또는 -1인지 확인

}

```

따라서 프로그래밍 시 모듈로 연산을 사용할 때는 해당 언어와 환경에서 나머지의 부호가 어떻게 처리되는지 명확히 이해하고 코드를 작성하는 것이 중요하다.

7. 확장된 모듈로 연산

수학에서 모듈로 연산의 결과는 동치류이며, 그 류의 모든 멤버는 대표원으로 선택될 수 있다. 일반적으로는 해당 류에 속하는 가장 작은 음이 아닌 정수인 '''최소 양의 나머지'''를 대표원으로 사용한다. 이는 유클리드 나눗셈의 나머지와 같다.[2] 하지만 다른 규칙도 사용될 수 있다. 컴퓨터와 계산기는 숫자를 저장하고 표현하는 방식이 다양하기 때문에, 모듈로 연산의 정의는 사용하는 프로그래밍 언어나 기본 하드웨어에 따라 달라질 수 있다.

거의 모든 컴퓨팅 시스템에서, ''a''를 ''n''으로 나눈 몫 ''q''와 나머지 ''r''은 다음 조건을 만족시킨다.

\begin{align}

&q \in \mathbb{Z} \\

&a = n q + r \\

&|r| < |n| \quad &(1)

\end{align}

여기서 \mathbb{Z}는 정수의 집합을 의미한다. 이 조건은 몫 ''q''가 정수이고, 원래 수 ''a''가 몫과 제수 ''n''의 곱에 나머지 ''r''을 더한 값과 같으며, 나머지 ''r''의 절댓값이 제수 ''n''의 절댓값보다 작아야 함을 나타낸다.

나머지 ''r''이 0이 아닐 경우, 부호에 대한 모호성이 생긴다. 식 (1)을 만족시키는 나머지는 두 가지 가능한 값(하나는 음수, 다른 하나는 양수)을 가지며, 이에 따라 몫 ''q''도 두 개의 연속된 정수 중 하나로 결정된다. 수론에서는 보통 양의 나머지를 선택하지만, 컴퓨팅 환경에서는 프로그래밍 언어나 피제수 ''a'' 또는 제수 ''n''의 부호에 따라 선택이 달라진다. 예를 들어, 표준 파스칼과 ALGOL 68은 제수가 음수일 때도 양수(또는 0) 나머지를 결과로 내놓는다. 반면, C90과 같은 일부 언어는 ''n''이나 ''a'' 중 하나가 음수일 때 나머지의 부호를 특정 구현에 맡긴다. ''a''를 0으로 나누는 연산(모듈로 0)은 대부분의 시스템에서 정의되지 않지만, 일부 시스템에서는 결과값을 ''a''로 정의하기도 한다.

컴퓨팅에서 사용되는 몇 가지 주요 모듈로 연산 정의는 다음과 같다.




절단 나눗셈 (Truncated division): 많은 구현에서 사용하는 방식으로, 몫 ''q''는 ''a''/''n''의 소수점 이하를 버리는 방식으로 계산된다 (q = \operatorname{trunc}(a/n)). 이 경우, 나머지 ''r''은 r = a - n \operatorname{trunc}(a/n)으로 계산되며, 피제수 ''a''와 같은 부호를 가진다.



바닥 나눗셈 (Floored division): 도널드 크누스가 지지한 방식으로[3], 몫 ''q''는 ''a''/''n''보다 작거나 같은 가장 큰 정수로 계산된다 (q = \lfloor a/n \rfloor, 바닥 함수). 이 경우, 나머지 ''r''은 r = a - n \lfloor a/n \rfloor으로 계산되며, 제수 ''n''과 같은 부호를 가진다.



유클리드 나눗셈 (Euclidean division): 레이먼드 T. 부테가 지지한 방식으로[4], 몫 ''q''는 q = \sgn(n) \lfloor a/|n| \rfloor으로 정의된다. 여기서 sgn은 부호 함수이다. 이 방식은 제수 ''n''의 부호에 따라 바닥 함수(\lfloor\,\rfloor) 또는 천장 함수(\lceil\,\rceil)를 사용한다 (q = \lfloor a/n \rfloor if n > 0, q = \lceil a/n \rceil if n < 0). 이 경우, 나머지 ''r''은 r = a - |n| \lfloor a/|n| \rfloor으로 계산되며, 항상 0 이상이다 (r \ge 0).



반올림 나눗셈 (Rounding division): Common Lisp와 IEEE 754 표준에서 사용하는 방식으로, 몫 ''q''는 ''a''/''n''을 반올림한 값이다 (q = \operatorname{round}(a/n)). 이 경우, 나머지 ''r''은 r = a - n \operatorname{round}(a/n)으로 계산되며, -|n|/2|n|/2 사이의 값을 가진다.



천장 나눗셈 (Ceiling division): Common Lisp에서 사용하는 또 다른 방식으로, 몫 ''q''는 ''a''/''n''보다 크거나 같은 가장 작은 정수로 계산된다 (q = \lceil a/n \rceil, 천장 함수). 이 경우, 나머지 ''r''은 r = a - n \lceil a/n \rceil으로 계산되며, 제수 ''n''과 반대 부호를 가지거나 0이다.

피제수 ''a''와 제수 ''n''이 모두 양수일 때는 절단, 바닥, 유클리드 정의가 동일한 결과를 낸다. 각 정의는 피제수와 제수의 부호 조합에 따라 다른 방식과 일치하기도 한다. 예를 들어, 피제수가 음수이고 제수가 양수이면 바닥 나눗셈과 유클리드 나눗셈이 같은 결과를 준다.

단 레이헌(Daan Leijen)은 다음과 같이 언급했다.

부테는 유클리드 나눗셈이 규칙성과 유용한 수학적 속성 면에서 다른 나눗셈보다 우수하다고 주장하며, 크누스가 지지하는 바닥 나눗셈 역시 좋은 정의이다. 널리 사용됨에도 불구하고, 절단 나눗셈은 다른 정의들보다 열등한 것으로 보인다.[5]


하지만 절단 나눗셈은 ({-a})/b = {-(a/b)} = a/({-b})라는 항등식을 만족시키는 장점이 있다.[6]

때로는 모듈로 연산의 결과가 0과 n-1 사이가 아니라, 특정 값 dd + n - 1 사이에 있도록 하는 것이 유용할 수 있다. 이 값 d오프셋(offset)이라고 부른다. 예를 들어 d=1로 설정하면 결과는 1부터 n까지의 범위에 있게 된다.

이 연산에 대한 표준 표기법은 없지만, 임시로 a \pmod_d n으로 표기할 수 있다. 이 연산의 정의는 다음과 같다:[60]

x = a \pmod_d nd \le x \le d + n - 1 이고 x \equiv a \pmod n (즉, xan으로 나눈 나머지가 같음)을 만족하는 유일한 값 x이다.

일반적인 모듈로 연산은 오프셋이 0인 경우(d=0)에 해당한다: a \pmod n = a \pmod_0 n.

오프셋을 갖는 모듈로 연산은 바닥 함수를 사용하여 다음과 같이 표현할 수 있다.

a \operatorname{mod}_d n = a - n \left\lfloor\frac{a-d}{n}\right\rfloor.

이 식은 a \pmod_d n이 일반적인 모듈로 연산 a \pmod n과 같은 동치류에 속하면서 범위가 [d, d+n-1]임을 보장한다. 이를 확인하기 위해, x = a - n \lfloor\frac{a-d}{n}\rfloor라고 하자. 먼저 x \equiv a \pmod n임을 보인다. 모든 정수 ''b''에 대해 (a + bn) \pmod n = a \pmod n이 성립하므로, b = -\lfloor\frac{a-d}{n}\rfloor일 때도 성립한다. 즉, x \pmod n = (a - n \lfloor\frac{a-d}{n}\rfloor) \pmod n = a \pmod n이다. 다음으로 d \le x \le d + n - 1임을 보인다. 유클리드 나눗셈에 의해 a - d = kn + r이고 0 \le r \le n - 1인 정수 ''k'', ''r''이 존재한다. 그러면 \lfloor\frac{a-d}{n}\rfloor = k이므로, x = a - n \lfloor\frac{a-d}{n}\rfloor = a - nk = d + r이다. 0 \le r \le n - 1의 각 변에 ''d''를 더하면 d \le d + r \le d + n - 1이 되고, x = d + r이므로 d \le x \le d + n - 1이 성립한다.

오프셋 모듈로 연산 a \pmod_d n은 Mathematica에서 `Mod[a, n, d]` 함수로 구현되어 있다.[60]

참조

[1] 웹사이트 Congruence https://mathworld.wo[...] 2020-08-27
[2] 웹사이트 residue https://primes.utm.e[...] 2020-08-27
[3] 서적 The Art of Computer Programming https://archive.org/[...] Addison-Wesley
[4] 간행물 The Euclidean definition of the functions div and mod http://portal.acm.or[...] ACM Press (New York, NY, USA) 1992-04
[5] 웹사이트 Division and Modulus for Computer Scientists https://www.microsof[...] 2001-12-03
[6] 웹사이트 Mod Function and Negative Numbers http://mathforum.org[...] 2001-07-05
[7] 웹사이트 Faster division and modulo operation - the power of two http://blog.teamlead[...] 2012-07-05
[8] 서적 ISO/IEC 8652:2012 - Information technology — Programming languages — Ada ISO, IEC
[9] 웹사이트 C99 specification (ISO/IEC 9899:TC2) http://www.open-std.[...] 2005-05-06
[10] 서적 ISO/IEC 14882:2003: Programming languages – C++ International Organization for Standardization, International Electrotechnical Commission
[11] 서적 ISO/IEC 9899:1990: Programming languages – C International Organization for Standardization, International Electrotechnical Commission
[12] 웹사이트 Math.IEEERemainder(Double, Double) Method (System) https://learn.micros[...] 2022-10-04
[13] 웹사이트 clojure.core - Clojure v1.10.3 API documentation https://clojure.gith[...] 2022-03-16
[14] 웹사이트 clojure.core - Clojure v1.10.3 API documentation https://clojure.gith[...] 2022-03-16
[15] 서적 ISO/IEC 1989:2023 – Programming language COBOL https://www.iso.org/[...] ISO 2023-01
[16] 웹사이트 CoffeeScript operators http://coffeescript.[...]
[17] 서적 ISO/IEC 23271:2012 — Information technology — Common Language Infrastructure (CLI) https://www.iso.org/[...] ISO 2012-02
[18] 웹사이트 mod() - CSS: Cascading Style Sheets {{!}} MDN https://developer.mo[...] 2024-06-22
[19] 웹사이트 rem() - CSS: Cascading Style Sheets {{!}} MDN https://developer.mo[...] 2024-10-15
[20] 웹사이트 Expressions - D Programming Language https://dlang.org/sp[...] 2021-06-01
[21] 웹사이트 operator % method - num class - dart:core library - Dart API https://api.dart.dev[...] 2021-06-01
[22] 웹사이트 remainder method - num class - dart:core library - Dart API https://api.dart.dev[...] 2021-06-01
[23] 웹사이트 Kernel — Elixir v1.11.3 https://hexdocs.pm/e[...] 2021-01-28
[24] 웹사이트 Integer — Elixir v1.11.3 https://hexdocs.pm/e[...] 2021-01-28
[25] 웹사이트 Basics - core 1.0.5 https://package.elm-[...] 2022-03-16
[26] 웹사이트 Basics - core 1.0.5 https://package.elm-[...] 2022-03-16
[27] 웹사이트 Erlang -- math https://erlang.org/d[...] 2021-06-01
[28] 서적 Programming Languages — Full BASIC https://archive.org/[...] American National Standards Institute 1987-01-28
[29] 서적 Programming Languages — Full BASIC https://archive.org/[...] American National Standards Institute 1987-01-28
[30] 웹사이트 GLSL Language Specification, Version 4.50.7 https://www.khronos.[...]
[31] 웹사이트 GLSL Language Specification, Version 4.50.7 https://www.khronos.[...]
[32] 웹사이트 The Go Programming Language Specification - The Go Programming Language https://go.dev/ref/s[...] 2022-02-28
[33] 웹사이트 math package - math - pkg.go.dev https://pkg.go.dev/m[...] 2022-02-28
[34] 웹사이트 big package - math/big - pkg.go.dev https://pkg.go.dev/m[...] 2022-02-28
[35] 웹사이트 big package - math/big - pkg.go.dev https://pkg.go.dev/m[...] 2024-04-12
[36] 웹사이트 6 Predefined Types and Classes https://www.haskell.[...] 2022-05-22
[37] 웹사이트 Operators https://docs.microso[...] Microsoft 2021-07-19
[38] 웹사이트 Mathematics · The Julia Language https://docs.juliala[...] 2021-11-20
[39] 웹사이트 Mathematics · The Julia Language https://docs.juliala[...] 2021-11-20
[40] 웹사이트 rem - Kotlin Programming Language https://kotlinlang.o[...] 2021-05-05
[41] 웹사이트 mod - Kotlin Programming Language https://kotlinlang.o[...] 2021-05-05
[42] 웹사이트 Chapter 3: The NASM Language https://nasm.us/doc/[...]
[43] 웹사이트 OCaml library : Stdlib https://ocaml.org/re[...] 2022-02-19
[44] 웹사이트 OCaml library : Stdlib https://ocaml.org/re[...] 2022-02-19
[45] Perl documentation Perl documentation http://perldoc.perl.[...]
[46] 웹사이트 PHP: Arithmetic Operators - Manual https://www.php.net/[...] 2021-11-20
[47] 웹사이트 PHP: fmod - Manual https://www.php.net/[...] 2021-11-20
[48] 웹사이트 EuclideanRing https://pursuit.pure[...]
[49] 웹사이트 Expressions https://docs.microso[...] 2018-07-11
[50] 웹사이트 R: Arithmetic Operators https://search.r-pro[...] 2022-12-24
[51] 웹사이트 F32 - Rust https://doc.rust-lan[...]
[52] r6rs.org r6rs.org http://www.r6rs.org/[...]
[53] 웹사이트 Shell Command Language https://pubs.opengro[...] 2021-02-05
[54] 웹사이트 Solidity Documentation https://docs.solidit[...] 2024-10-17
[55] 웹사이트 Apple Developer Documentation https://developer.ap[...] 2021-11-20
[56] 웹사이트 Apple Developer Documentation https://developer.ap[...] 2021-11-20
[57] 웹사이트 Apple Developer Documentation https://developer.ap[...] 2021-11-20
[58] 웹사이트 WebAssembly Core Specification: Version 2.0 https://www.w3.org/T[...] World Wide Web Consortium 2022-04-19
[59] 웹사이트 Zig Documentation https://ziglang.org/[...] 2022-12-18
[60] 웹사이트 Mod https://reference.wo[...] Wolfram Research 2020-04-08
[61] 웹사이트 MSDN 剰余演算子 (%) https://msdn.microso[...] マイクロソフト 2015-12-09
[62] 웹사이트 ASCII.jpデジタル用語辞典 モジュロ http://yougo.ascii.j[...] https://ascii.jp/ 2015-12-09
[63] IT用語辞典 e-Words 剰余演算(モジュロ演算 / mod)とは - 意味をわかりやすく https://e-words.jp/w[...]
[64] 英辞郎 on the WEB moduloの意味・使い方・読み方 https://eow.alc.co.j[...]
[65] cpprefjp C++日本語リファレンス 整数に対する除算と剰余算の丸め結果を規定 https://cpprefjp.git[...]
[66] 서적 The Art of Computer Programming Addison-Wesley
[67] 간행물 The Euclidean definition of the functions div and mod http://portal.acm.or[...] ACM Press (New York, NY, USA) 1992-04
[68] 웹사이트 Division and Modulus for Computer Scientists http://research.micr[...] 2014-12-25
[69] 웹사이트 Faster division and modulo operation - the power of two http://blog.teamlead[...] 2015-12-09
[70] 문서 ISO/IEC 14882:2003 : Programming languages -- C++ ISO, IEC
[71] 문서 open-std.org, section 6.5.5 http://www.open-std.[...]
[72] 웹사이트 CoffeeScript operators http://coffeescript.[...]
[73] 웹사이트 Expressions http://www.digitalma[...] Digital Mars 2010-07-29
[74] 웹사이트 Mod() http://www.purebasic[...] Fantaisie Software 2015-12-09
[75] 웹사이트 r6rs.org http://www.r6rs.org/[...]
[76] 웹사이트 Math.IEEERemainder(Double, Double) Method (System) | Microsoft Learn https://learn.micros[...]
[77] 간행물 ISO/IEC 9899:1990 : Programming languages -- C ISO, IEC
[78] 웹인용 Congruence https://mathworld.wo[...] 2020-08-27



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com