Lab 3-3: IEEE-754 誤差計算 (20%)
- 輸入:以 10 為底的實數。
- 實數的正負號 (sign),正負號輸入大於等於 0 為正數,小於 0 為負數。
- 實數的尾數 (mantissa),尾數部分固定 9 位數字,第一位不為
0
,數值為輸入數字乘以\( \frac{1}{100,000,000} \),。 - 實數的指數部分 (exponent),指數部分為 -38 至 +38。
- 輸出:
- 該實數的科學記號表示,有效位數為 9 位。
- 該實數的 IEEE-754 single precision 數值,以科學記號表示,有效位數 (Significant figures - Wikipedia) 顯示固定為 9 位。
- 該實數與 IEEE-754 single precision 數值的差異絕對值,以科學記號表示,有效位數 (Significant figures - Wikipedia) 顯示固定為 9 位。
- 檔名:lab3_3_<學號>.cpp (e.g. lab3_3_106062802.cpp)
程式需提示使用者輸入實數的正負號 (sign)、實數的尾數 (mantissa,輸入數字乘以\( \frac{1}{100,000,000} \))、實數的指數部分 (exponent),輸出該實數的科學記號表示、該實數的 IEEE-754 single precision 數值、該實數與 IEEE-754 single precision 數值的差異絕對值。
Format
Input real number, sign: <sign>⏎
Input real number, mantissa: <mantissa>⏎
Input real number, exponent: <exponent>⏎
The real number is: <output real number>
The IEEE-754 single precision number is: <output float value>
The difference (absolute value): <difference in abs>
Example
$ ./a.out
Input real number, sign: -100⏎
Input real number, mantissa: 123456789⏎
Input real number, exponent: 10⏎
The real number is: -1.23456789e+10
The IEEE-754 single precision number is: -1.23456788e+10
The difference (absolute value): 1.00000000e+02
Reference Code:
#include <iostream>
#include <iomanip>
#include <cmath>
int main(void)
{
long int a = -100, b = 123456789, c = 7;
float c_exp = std::pow(10.0, (double)c);
double b_mantissa = (float)b * 1e-8;
double b_mantissa_double = (double)b * 1e-8;
a = (a >= 0 ? 1 : -1);
float d = a * b_mantissa * c_exp;
double d_real = a * b_mantissa_double * c_exp;
double mantissa_diff = d - d_real;
mantissa_diff = (mantissa_diff >= 0 ? mantissa_diff : mantissa_diff * -1); // abs()
// round mantissa difference
double mantissa_diff_round_unit = std::pow(10.0, (double)c - 8);
double mantissa_diff_quotient = std::round(mantissa_diff / mantissa_diff_round_unit);
// unit is 10^(c-8), because the significant digits are 9 digits
// and with a leading digit, the least significant digit is
// 10^-8 smaller than the leading digit. Thus, the mantissa difference
// must round to 10^(c-8).
mantissa_diff = mantissa_diff_round_unit * mantissa_diff_quotient;
std::cout << "a: " << a << std::endl
<< "b: " << b << std::endl
<< "c: " << c << std::endl
<< std::scientific << std::setprecision(8)
<< d << std::endl
<< d_real << std::endl
<< mantissa_diff << std::endl;
return 0;
}