固定小数点

 投稿者:minmi  投稿日:2014年12月 1日(月)20時05分8秒
  大学で数値計算について学んでいる者です.
今,C言語でdouble型の数をscanfで読み取り,読み込んだdouble型の浮動小数点数を
固定小数点数に変換し四則演算を行うプログラムを書きたいのですが,うまく書けません.
よろしければ,例となるようなプログラムを書いていただけませんでしょうか?
よろしくお願いします.
 

Re: 固定小数点

 投稿者:山中和義  投稿日:2014年12月 2日(火)18時51分6秒
  > 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ビット整数で計算しないといけません。

 

戻る