복식에 계수를 사용할 수 없습니까?


185

C ++ (g ++을 사용하여 컴파일 됨)의 프로그램이 있습니다. 모듈 함수에 피연산자로 두 개의 이중을 적용하려고하지만 다음 오류가 발생합니다.

오류 : 'double'및 'double'유형의 이진 'operator %'에 유효하지 않은 피연산자

코드는 다음과 같습니다.

int main() {
    double x = 6.3;
    double y = 2;
    double z = x % y;
}

12
앞서 언급했듯이 fmod ()는 필요한 기능을 제공합니다. 아직 언급되지 않았지만 두 번째 피연산자의 반올림 오류가 fmod예기치 않은 동작을 유발할 수 있음 을 인식하는 것이 중요합니다 . 예를 들어 fmod(1, 0.1);수학적으로 0이어야하지만 실제로는 거의 0.1입니다. 오차의 정도는 몫의 크기와 함께 올라갑니다. 예를 들어 fmod(9E14, 0.1);수학적 관점에서 볼 때 약 0.05로 평가됩니다.
supercat 2016 년

1
@ supercat 자세한 내용은 굉장합니다. 나는 당신이 말하는 것을 사실로 만들기 위해 배후에 무엇이 있는지에 대한 아이디어를 가지고 있다고 생각하지만, 당신이 말하는 것이 진실 인 이유를 보는 것이 좋을 것입니다. 그것이 무대 뒤에서 어떻게 작동하는지 보는 것은 흥미로울 것입니다 (나는 이해하지만 매우 쉽게 잘못 될 수 있다고 생각합니다).
RastaJedi

3
부동 소수점 값은 정확한 정수 배수 또는 2의 거듭 제곱을 나타냅니다. 예를 들어 정수 리터럴 0.1은 정확히 3602879701896397/36028797018963968입니다 (후자는 2의 거듭 제곱입니다). fmod(x,0.1)x를 정확한 분수로 나누고 숫자 값 "1/10"으로 나누지 않고 나머지를 취합니다.
supercat

답변:


272

%연산자는 정수입니다. 당신은 fmod()기능을 찾고 있습니다 .

#include <cmath>

int main()
{
    double x = 6.3;
    double y = 2.0;
    double z = std::fmod(x,y);

}

Qt 용 C ++로 프로그래밍 중이며 fmod에 버그가 있습니다. fmod (angle, 360)의 결과는 360 (WAT ?!)입니다.
Paul

7
@ 폴 : 아마도 버그가 아닙니다. 경우 angle이며, 말, 359.9999999후 모두 anglefmod(angle, 360)가능성으로 표시 할 수 있습니다 360. (필요한 경우 9를 더 추가하십시오.) 예를 들어 50 자리의 정밀도로 값을 인쇄 해보십시오.
Keith Thompson

@Paul Qt의 QString :: format은 반올림됩니다. 그것이 중요한 경우, 당신은 자신을 반올림하거나 "360"에 대한 출력을 확인하고 자신의 값으로 대체해야합니다.
jfh

38

fmod(x, y) 사용하는 기능입니다.


5

사용 fmod()에서 <cmath>. C 헤더 파일을 포함하지 않으려는 경우 :

template<typename T, typename U>
constexpr double dmod (T x, U mod)
{
    return !mod ? x : x - mod * static_cast<long long>(x / mod);
}

//Usage:
double z = dmod<double, unsigned int>(14.3, 4);
double z = dmod<long, float>(14, 4.6);
//This also works:
double z = dmod(14.7, 0.3);
double z = dmod(14.7, 0);
double z = dmod(0, 0.3f);
double z = dmod(myFirstVariable, someOtherVariable);

3
C 헤더 파일을 포함하지 않으려는 이유는 무엇입니까? 그것이 거기에있는 것입니다.
Keith Thompson

2

이를 위해 자체 모듈러스 함수구현할 수 있습니다 .

double dmod(double x, double y) {
    return x - (int)(x/y) * y;
}

그런 다음 간단히 dmod(6.3, 2)나머지를 얻는 데 사용할 수 있습니다 0.3.


여전히 완벽한 솔루션은 아닙니다. x = 10.499999999999998, y = 0.69999999999999996은 0.0 대신에 0.69999999999999929를 반환합니다.
tarpista
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.