Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 부동 소수점 조작 함수 완벽 정리

컴퓨터에서 소수는 부동 소수점(floating point) 방식으로 표현됩니다. C++에서 float 자료형은 일반적으로 32비트 크기를 가지며, 이러한 부동 소수점 숫자를 다루는 다양한 함수들이 <cmath> 헤더에 정의되어 있습니다. 이번 글에서는 대표적인 부동 소수점 조작 함수들의 용도와 사용법을 예제 코드와 함께 하나씩 살펴보겠습니다.

fmod() – 나눗셈의 나머지 구하기

fmod() 함수는 전달된 두 인자를 나누었을 때의 나머지를 반환합니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main() {
    float a, b, rem;
    a = 23.4;
    b = 4.1;
    rem = fmod(a, b);
    cout<<"fmod("<<a<<", "<<b<<")의 값 = "<<rem;
}

출력 결과

fmod(23.4, 4.1)의 값 = 2.9

remainder() – 최소 나머지 구하기

remainder() 함수도 fmod와 마찬가지로 나눗셈의 나머지를 구하지만, 중요한 차이점이 있습니다. remainder()는 수학적으로 가능한 가장 작은 나머지를 반환하며, 그 결과는 음수가 될 수도 있습니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main() {
    float a, b, rem;
    a = 23.4;
    b = 4.1;
    rem = remainder(a, b);
    cout<<"remainder("<<a<<", "<<b<<")의 값 = "<<rem;
}

출력 결과

remainder(23.4, 4.1)의 값 = -1.2

remquo() – 몫과 나머지를 동시에 구하기

remquo() 함수는 두 값의 나머지뿐만 아니라 몫까지 함께 구할 수 있는 함수입니다. 함수 호출 시 몫을 저장할 int 변수의 참조(포인터)를 세 번째 인자로 전달하면, 반환값으로는 remainder()와 동일한 방식의 최소 나머지를 돌려주고, 참조된 변수에는 몫이 저장됩니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main() {
    float a, b, rem;
    int quo;
    a = 23.4;
    b = 4.1;
    rem = remquo(a, b, &quo);
    cout<<a<<"과 "<<b<<"를 remquo() 함수에 전달한 결과\n";
    cout<<"나머지: "<<rem<<endl;
    cout<<"몫: "<<quo;
}

출력 결과

23.4과 4.1를 remquo() 함수에 전달한 결과
나머지: -1.2
몫: 6

copysign() – 부호 복사하기

copysign() 함수는 첫 번째 인자의 크기(magnitude)와 두 번째 인자의 부호를 결합한 값을 반환합니다. 즉, 반환값의 절댓값은 첫 번째 인자와 같고, 부호는 두 번째 인자를 따르게 됩니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    double a, b;
    a = 9.6;
    b = -3.5;
    cout<<"입력값 "<<a<<"과 "<<b<<"에 대한 copysign 결과: "<<copysign(a, b);
}

출력 결과

입력값 9.6과 -3.5에 대한 copysign 결과: -9.6

fmin() – 최솟값 구하기

fmin() 함수는 이름 그대로 두 인자 중 더 작은 값을 반환합니다. 반환 타입은 부동 소수점이며, NaN처럼 특수한 값이 섞여 있어도 안정적으로 동작한다는 장점이 있습니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    double a, b;
    a = 43.5;
    b = 21.2;
    cout << a<<"과 "<<b<<" 중 더 작은 값은 ";
    cout << fmin(a, b)<<endl;
}

출력 결과

43.5과 21.2 중 더 작은 값은 21.2

fmax() – 최댓값 구하기

fmax() 함수는 두 인자 중 더 큰 값을 반환하는 함수입니다. fmin()과 마찬가지로 특수한 부동 소수점 값에 대해서도 안정적인 동작을 보장합니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    double a, b;
    a = 43.5;
    b = 21.2;
    cout << a<<"과 "<<b<<" 중 더 큰 값은 ";
    cout << fmax(a, b)<<endl;
}

출력 결과

43.5과 21.2 중 더 큰 값은 43.5

fdim() – 양의 차이 구하기

fdim() 함수는 두 인자 간의 양의 차이(positive difference)를 반환합니다. 첫 번째 인자가 두 번째 인자보다 크면 두 값의 차이를, 그렇지 않으면 0을 반환합니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    double a, b;
    a = 43.5;
    b = 21.2;
    cout << a<<"과 "<<b<<"의 차이는 ";
    cout << fdim(a, b)<<endl;
}

출력 결과

43.5과 21.2의 차이는 22.3

fma() – 융합 곱셈-덧셈 연산

fma() 함수는 Fused Multiply-Add의 약자로, 세 개의 인자 x, y, z에 대해 x × y + z 연산을 한 번의 명령으로 수행합니다. 중간 결과를 반올림하지 않고 계산하기 때문에 곱셈과 덧셈을 따로 수행하는 것보다 정확도가 높고 속도 면에서도 유리합니다.

예제

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    double a, b, c;
    a = 3.5;
    b = 2.4;
    c = 7.2;
    cout << a<<" × "<<b<<" + "<<c<<"의 결과는 ";
    cout << fma(a, b, c)<<endl;
}

출력 결과

3.5 × 2.4 + 7.2의 결과는 15.6

마무리

지금까지 <cmath> 라이브러리에서 제공하는 대표적인 부동 소수점 조작 함수들을 알아보았습니다. fmod와 remainder의 나머지 계산부터 remquo의 몫·나머지 동시 처리, copysign의 부호 조작, 그리고 fmin, fmax, fdim, fma까지, 이 함수들을 적절히 활용하면 실수 연산을 더욱 정확하고 편리하게 처리할 수 있습니다.