|
> No.3564[元記事へ]
minmiさんへのお返事です。
> 今,C言語でdouble型の数をscanfで読み取り,読み込んだdouble型の浮動小数点数を
> 固定小数点数に変換し四則演算を行うプログラムを書きたいのですが,うまく書けません.
> よろしければ,例となるようなプログラムを書いていただけませんでしょうか?
固定小数点の仕様がはっきりしませんので、システムが扱う整数の範囲で考えてみます。
整数の四則演算ができるとする。
右から4桁目(固定位置)が一の位と仮定して、小数点を含む数 123.45 を、123450 と表現する。
LET K=10^3 !小数点以下は3桁
LET X=123.45
LET Y= 67.8
LET A=INT(X*K) !符号化
LET B=INT(Y*K)
PRINT A; B
LET W=A+B !整数による演算
LET S=A-B
LET M=INT(A*B/K)
LET D=INT(A*K/B)
PRINT W; S; M; D
PRINT W/K; S/K; M/K; D/K !復号化
!検算
PRINT X+Y; X-Y; X*Y; X/Y
END
実行結果
123450 67800
191250 55650 8369910 1820
191.25 55.65 8369.91 1.82
191.25 55.65 8369.91 1.82079646017699
C言語(BCPad 2.3.1 + Borland C++ Compiler 5.5.1)に翻訳すると、
#include <stdio.h>
#define K 1000 //小数点以下は3桁
int main(void)
{
double x,y;
long a,b, w,s,m,d;
scanf("%lf", &x); //x=123.45;
scanf("%lf", &y); //y= 67.8;
a=x*K; //符号化
b=y*K;
printf("%d %d\n", a, b);
w=a+b; //整数による演算
s=a-b;
m=a*b/K;
d=a*K/b;
printf("%ld %ld %ld %ld\n", w,s,m,d);
printf("%.3f %.3f %.3f %.3f\n", (float)w/K, (float)s/K,(float)m/K, (float)d/K); //復号化
printf("%f %f %f %f\n", x+y, x-y, x*y, x/y); //検算
return 0;
}
実行結果
123.45(改行)
67.8(改行)
123450 67799
191249 55651 -220148 1820
191.249 55.651 -220.148 1.820
191.250000 55.650000 8369.910000 1.820796
-- Press any key to exit (Input "c" to continue) --
乗算a*bでオーバーフロー(32ビット整数)が発生しているため正しい結果が得られません。
この場合、a/K*bならオーバーフローは発生しませんが、精度が落ちます。
ここは、64ビット整数で計算しないといけません。
|
|