fma() คืออะไร?
fma() (Fused Multiply-Add) เป็นฟังก์ชันในตัวของไฟล์หัวข้อ <cmath> ซึ่งรับพารามิเตอร์สามตัว x, y และ z และส่งคืนผลลัพธ์ x * y + z โดยไม่สูญเสียความแม่นยำในผลลัพธ์ระหว่างทาง (intermediate result)
ในการคำนวณทั่วไป x * y + z จะมีการปัดเศษ (rounding) สองครั้ง: ครั้งแรกหลังคูณ x * y และครั้งที่สองหลังบวก z แต่ fma() คำนวณในขั้นตอนเดียวด้วยความแม่นยำสูงกว่า (มักใช้ฮาร์ดแวร์ FMA instruction) จึงลดข้อผิดพลาดจากการปัดเศษได้
ไวยากรณ์ (Syntax)
float fma(float x, float y, float z); double fma(double x, double y, double z); long double fma(long double x, long double y, long double z);
พารามิเตอร์ (Parameters)
- x - องค์ประกอบแรกที่จะคูณ
- y - องค์ประกอบที่สองที่จะคูณกับ x
- z - องค์ประกอบที่สามที่จะบวกเข้ากับผลคูณของ x และ y
ค่าที่ส่งคืน (Return Value)
ส่งคืนผลลัพธ์ที่แม่นยำของ x * y + z
ตัวอย่างที่ 1
#include <cmath>
#include <iostream>
using namespace std;
int main() {
double x = 2.1, y = 4.2, z = 9.4, answer;
answer = fma(x, y, z);
cout << x << " * " << y << " + " << z << " = " << answer << endl;
return 0;
}
ผลลัพธ์ (Output)
2.1 * 4.2 + 9.4 = 18.22
ตัวอย่างที่ 2
#include <cmath>
#include <iostream>
using namespace std;
int main() {
double a = 7.4, b = 9.3, c = 1.2;
double ans = fma(a, b, c);
cout << a << " * " << b << " + " << c << " = " << ans << endl;
return 0;
}
ผลลัพธ์ (Output)
7.4 * 9.3 + 1.2 = 70.02
ข้อดีของ fma():
- ความแม่นยำสูงกว่า: ปัดเศษเพียงครั้งเดียวหลังคำนวณ x*y+z ทั้งหมด
- ประสิทธิภาพ: บนฮาร์ดแวร์ที่รองรับ FMA instruction (เช่น x86-64 with FMA, ARM NEON) จะทำงานเร็วกว่า
- หลีกเลี่ยง overflow/underflow ระหว่างทางในบางกรณี
หมายเหตุ: ต้องคอมไพล์ด้วย flag -mfma (GCC/Clang) เพื่อใช้ประโยชน์จากฮาร์ดแวร์ FMA instruction