Nice programing

계수 나누기 (%)가 정수에서만 작동하는 이유는 무엇입니까?

nicepro 2020. 10. 18. 19:35
반응형

계수 나누기 (%)가 정수에서만 작동하는 이유는 무엇입니까?


최근에 모듈러스 나누기를 사용하여 쉽게 해결할 수 있는 문제발생 했지만 입력은 부동 소수점이었습니다.

주기 함수 (예 sin:)와주기 범위 내에서만 계산할 수있는 컴퓨터 함수 (예 : [-π, π])가 주어지면 모든 입력을 처리 할 수있는 함수를 만듭니다.

"명백한"해결책은 다음과 같습니다.

#include <cmath>

float sin(float x){
    return limited_sin((x + M_PI) % (2 *M_PI) - M_PI);
}

왜 작동하지 않습니까? 이 오류가 발생합니다.

error: invalid operands of types double and double to binary operator %

흥미롭게도 Python에서 작동합니다.

def sin(x):
    return limited_sin((x + math.pi) % (2 * math.pi) - math.pi)

"나머지"의 일반적인 수학적 개념은 정수 나눗셈에만 적용 할 수 있기 때문입니다. 즉, 정수 몫을 생성하는 데 필요한 나눗셈.

"나머지"개념을 실수로 확장하려면 실제 피연산자에 대해 정수 몫을 생성하는 새로운 종류의 "하이브리드"연산을 도입해야합니다 . Core C 언어는 이러한 작업을 지원하지 않지만 표준 라이브러리 기능과 C99의 기능 으로 제공됩니다 . (이러한 함수는 동일하지 않고 몇 가지 특징이 있습니다. 특히 정수 나누기의 반올림 규칙을 따르지 않습니다.)fmodremainder


당신은 fmod ()를 찾고 있습니다.

나는 더 구체적으로 귀하의 질문에 대답하고 싶습니다. 이전 언어에서는 %연산자가 정수 모듈 식 나눗셈으로 정의되었고 최신 언어에서는 연산자의 정의를 확장하기로 결정했습니다.

편집 : 내가 왜 추측을 내기한다면, 모듈 식 산술의 아이디어가 정수론에서 유래하고 특히 정수를 다루기 때문이라고 말할 것입니다.


확실히 말할 수는 없지만 대부분 역사적이라고 생각합니다. 상당수의 초기 C 컴파일러는 부동 소수점을 전혀 지원하지 않았습니다. 나중에 추가되었지만 완전히는 아니지만 대부분 데이터 유형이 추가되었고 언어에서 가장 원시적 인 작업이 지원되었지만 나머지는 모두 표준 라이브러리에 남겨졌습니다.


%C와 C ++ 의 모듈로 연산자 는 두 개의 정수에 대해 정의되지만 fmod()double과 함께 사용할 수 있는 함수가 있습니다.


제약은 표준에 있습니다.

C11 (ISO / IEC 9899 : 201x) §6.5.5 곱셈 연산자

각 피연산자는 산술 유형을 가져야합니다. % 연산자의 피연산자는 정수 유형을 가져야합니다.

C ++ 11 (ISO / IEC 14882 : 2011) §5.6 곱셈 연산자

* 및 /의 피연산자는 산술 또는 열거 유형을 가져야합니다. %의 피연산자는 정수 또는 열거 유형을 가져야합니다. 일반적인 산술 변환은 피연산자에서 수행되며 결과 유형을 결정합니다.

해결책 은를 사용하는 것입니다. 이것이 바로 C99 Rationale §6.5.5 곱셈 연산자 에 따라 fmod의 피연산자 %가 정수 유형으로 제한되는 이유입니다 .

C89위원회는 % 연산자를 플로팅 유형에 대한 작업으로 확장하는 것을 거부했습니다. 이러한 사용은 fmod에서 제공하는 기능을 복제 할 것입니다.


시험 fmod


% 연산자는 숫자의 REMAINDER (계수에 대한 다른 이름)를 제공합니다. C / C ++의 경우 정수 연산에 대해서만 정의됩니다. 파이썬은 조금 더 넓으며 숫자를 몇 번 나눌 수 있는지 나머지에 대해 부동 소수점 숫자의 나머지를 얻을 수 있습니다.

>>> 4 % math.pi
0.85840734641020688
>>> 4 - math.pi
0.85840734641020688
>>> 

%당신이 두 유형의 두 숫자의 나머지 찾을하려고 할 때 연산자는, C ++에서 작동하지 않습니다 Float또는 Double.

따라서 / 에서 fmod함수를 사용해 보거나 해당 헤더 파일을 사용하지 않도록 다음 코드 줄을 사용할 수 있습니다.math.hcmath.h

float sin(float x) {
 float temp;
 temp = (x + M_PI) / ((2 *M_PI) - M_PI);
 return limited_sin((x + M_PI) - ((2 *M_PI) - M_PI) * temp ));

}


"The mathematical notion of modulo arithmetic works for floating point values as well, and this is one of the first issues that Donald Knuth discusses in his classic The Art of Computer Programming (volume I). I.e. it was once basic knowledge."

The floating point modulus operator is defined as follows:

m = num - iquot*den ; where iquot = int( num/den )

As indicated, the no-op of the % operator on floating point numbers appears to be standards related. The CRTL provides 'fmod', and usually 'remainder' as well, to perform % on fp numbers. The difference between these two lies in how they handle the intermediate 'iquot' rounding.

'remainder' uses round-to-nearest, and 'fmod' uses simple truncate.

If you write your own C++ numerical classes, nothing prevents you from amending the no-op legacy, by including an overloaded operator %.

Best Regards

참고URL : https://stackoverflow.com/questions/6102948/why-does-modulus-division-only-work-with-integers

반응형