• ベストアンサー

小数の計算の精度について

Perlでプログラムを作成しているのですが、小数の乗算を行う際に、計算が合わなくなって困っています。 例: 10000*1.005=10049 コンピューターの性質上、小数の乗算等は精度に問題があるのは分かっているのですが。 VB等では変数の型をうまく設定すれば計算出来るのですが、Perlではどのような方法でこの現象を回避できるのでしょうか。 もし、よい知恵がありましたらよろしくお願いします。

  • pco
  • お礼率44% (8/18)
  • Perl
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
noname#25358
noname#25358
回答No.2

 実際の数値ということですが、それはあきらかにおかしいです(^_^;  Perl そのものが内部で破壊されているか、プログラムにバグがあるか、コンピュータ自身がバグつきペンティアムを載せているかです。  たかだか8桁の数字で狂うことは、通常であればありえません。  printf のところに、%d を使ってませんか?  これは本来小数点なしの整数を表すためのものですので、単精度整数以上を扱う場合は %f を使うのが望ましいのです。  まずはこれを確認してみてください。

pco
質問者

お礼

回答ありがとうございます。 確認したところ、計算処理後にintで整数に変換しておりました。 その部分を修正しますと計算が正確に出来るようになりました。 ありがとうございました。

その他の回答 (1)

noname#25358
noname#25358
回答No.1

 数値はただのサンプルですよね?  実際にはどのような問題が発生しているのでしょうか。  Perl では、全ての変数が内部で自動切換えで制御されているので、一度1000倍にするなりなんなりしてから計算したり、または数字の文字列を自前の計算ロジックで計算させたりといった方法をとるしかありません。  ですので、ケースによってその対処法は変わってきますので、実際の不具合をみないと、これ、といった方法はないのです。  また、Perl はたしか倍制度整数までちゃんとサポートしていたはずなので、サンプルに記載された程度の数値を扱っているレベルであれば、心配は無意味です。

pco
質問者

補足

例の数値は実際の数値です。 状況的には 単価(整数8ケタ)×数量(整数部5ケタ、小数部3ケタ)=金額(整数9ケタ) という計算になります。 やはり、処理的には文字列で計算を行うのが一番よい方法ということになるのでしょうか。

関連するQ&A

  • 小数計算について

    お世話になります。 以下の小数計算方法を教えてください。 時間取得を DWORD start,end; start = start = timeGetTime(); for(int i =0; i<100000; i++){ 何らかの処理; } end = timeGetTime(); int msec = end-start; 上記 msecを1000で割った場合、 小数になるのですが、その場合、小数の変数の型は 何になるのでしょうか? また、求めた小数を用いて、 INT型の変数÷求めた小数 = 小数値(小数第2位まで) を行いたいです。 例えば、 840000 / 64.9 = 12942.99 のような処理をしたいです。 どうぞよろしくお願い致します。

  • 浮動小数点の精度と範囲からすると、「0」はどうなるのでしょうか

    IEEE754の単精度による浮動小数点表現(符号部1ビット、指数部8ビット、仮数部23ビット)ですと、その表現できる範囲が数値の絶対値で、2^(-126)=1.2×10^(-38)から(2 - 2^(-23))×2^(127)=3.4×10^(38)になりますが、数値の「0」はどう表現されるのでしょうか。たとえば、C言語などで、変数の値が「0」の場合、コンピュータ内部の2進数表現はどのようになっているのでしょうか。よろしくお願いいたします。

  • 小数点第2位の数値の計算

    下記のような処理があるとします。 Dim 変数1 As 宣言 Dim 変数2 As 宣言 Dim 変数3 As 宣言 Dim 変数4 As 宣言 変数1 = 0 変数2 = 0 変数3 = 0 変数4 = 0 変数1 = テキストボックス1.Text 変数2 = ラベル2.Caption 変数3 = ラベル3.Caption 変数4 = (変数2 + 変数3) - 変数1 ラベル4.Caption = 変数4 変数1~3には、小数点第2位までの 数値が入る事があるのですが、 例) 変数1 = 3.0 変数2 = 4.75 変数3 = 7.75 の場合、変数4 = 0 と計算される。 その場合、変数4の計算結果が 正しく出力されません。 宣言はDoubleを使うと計算結果は 16進数表示になり、Singleを使うと0になります。 正しい計算結果を出すには どのようにすれば良いでしょうか?

  • MATLABの計算精度

    いま,  A=[0.803, -0.803, 1.2124, 0.803, -0.803, -0.803, 1.2124, 0.803]; とします. このとき,次の2通りの演算をします. (i) a=0; for I=1:8  if( A(I)>=0 )   a=a+A(I)*0.25;  else   a=a+A(I)*0.75;  end end (ii) Bi=[0.25, 0.75, 0.25, 0.25, 0.75, 0.75, 0.25, 0.25]; b=sum(Bi.*A); (i)と(ii)によって得られる和の値をMATLABのコマンド上で表示すると, 同じ値として表示されるのですが,a-b と計算すると,0 ではなく, 8.04e-15のようになります.(現環境ではMATLABが使えないので,確認できませんが,もっと大きいデータでやったとき場合には,上記のように誤差が生じました). 困っているのは,現在組んでいるプログラムでは計算した値の正負によって 異なった計算をする必要があり,計算精度が非常に重要になってきます. そのため計算結果が例えば +1.4e-15となるか -6.4e-16 となるかによってその後の計算結果が大きく変わってしまいます. MATLABでは,上記(i)(ii)のような誤差が生じるためか,+1.4e-15となってほしいところが,なぜか -6.4e-16となってしまいうまくプログラムが動きません. MATLABでは,for文によって和をとるのではなく,一回でまとめて計算しなければ誤差が生じるのでしょうか? また,MATLABで計算精度を変更できないのでしょうか? (formatコマンドによって,「format short g」「format double g」としましたが有効な小数点が増減するだけで結果は同じでした.) よりよい精度で計算するにはどうしたらよいのでしょうか? 回答よろしくお願いします.

  • double型で収まりきれない小数の値を求めたい。

    下記のようなプログラムを作っています。 int num = 1000; double d1 = 12345.6; double d2 = 0.0: for(int i=0;i<num;i++){   d2 += Math.pow(d1,(double)i); } d2の値を求めたいのですが、これをこのまま実行すると、得られる数値が大きすぎてd2の値がInfinityになってしまいます。 小数を格納できる最大の型はdouble型ですよね? それに収まりきらないということは、私の求めたい数値はJavaでは求めることが出来ないのでしょうか? それとも何かInfinityになってしまうのを回避する手段はあるのでしょうか? d2で得られた値はそのまま他の計算式で利用するのでどうしてもすべて小数値でなくてはならないのです。 どなたかお知恵をお貸しください。 よろしくお願いします!!

    • ベストアンサー
    • Java
  • データ型について

    VBに限ったことではないのですが、 データ型には、短整数型、整数型、長整数型、単精度浮動小数点数型、倍精度浮動小数点数型といろいろな型がありますが、 整数を扱うなら長整数型、小数も含めて扱うなら倍精度浮動小数点数型 を使えば良いと思うのですが、それにより桁数の小さな短整数型、整数型とかは何のためにあるのでしょうか? あまり大きな値を扱わないときにそちらの型を選ぶメリットは何なのでしょうか?

  • 実数の整数部,小数部の取得

    OS:windows2000pro VB:VB6.0sp5 実数 num(変数) [as currency]  (但し 小数点以下2位まで)の値の 1.整数部 num_int(変数) [as long] 2.小数部 num_dec(変数) [as long] を上記変数に格納するのは、どのようにすればいいのでしょうか? (例1)num = 123.02 の場合、num_int=123, num_dec=2 (例2)num = 4.20 の場合、num_int= 4, num_dec=20 (例3)num = 0.23 の場合、num_int= 0, num_dec=23  よろしくお願いいたします

  • 小数点以下の検知

    とつぜん失礼します。VB.Netを使用しています。 計算結果が小数点以下 たとえば"25.6"だった場合10倍して整数化する プログラムを書きたいのですが、調べてもわかりません。 すみませんが誰かお教えください。

  • variant型にした場合、精度は落ちるのでしょうか?

    スピードや.NETに移行する場合は、currency型のままで良いのはわかりますが、より広い型を扱うようにバリアント型にしました。 同じようにint, long, single, double, currency型のデータをvariant型にして計算した場合の精度について詳しい方、教えてください。 また、COM+でVARIANT型みたいなのがあるようですが、VBのバリアントと同じものなのでしょうか?

  • マクロ変数 single で小数点計算が狂います

    Windows8.1 エクセル2010です。 マクロを使っており、小数点の計算をしたいため、初めてsingle double の変数を使いました。 例として、 Sub シングル() Dim 足される As Single Dim 足す As Single Dim 合計 As Single 足される = Range("a1").Value 足す = Range("b1").Value 合計 = 足される + 足す Range("c1").Select ActiveCell.FormulaR1C1 = 合計 End Sub A1=2.1 B1=5.1 普通は7.2となるのですが、7.19999980926513 と出ました。 doubleに変数を切り替えたら、ちゃんと7.2と出ました。 singleの仕組みがよくわかりません。 有効桁数数は「7桁」なら、小数点第7位まで扱える…という単純なものではないのでしょうか?

専門家に質問してみよう