• 締切済み

浮動小数点の誤差のあわせ方

文字列からdouble型変換で他のPGと誤差がでてしまうのですが、 なんとか同じBinaryにしたいので教えてください。 1.489を他のPGのHEXで表した結果では、 printf("1.489 = %08lx%08lx\n", atof((double)???)); >3ff7d2f1a9fbe76c 私の作ったPGでは printf("1.489 = %08lx%08lx\n", atof("1.489")); >3ff7d2f1a9fbe76d の結果になります。 丸めれば、同じになるような気がしますが、 その方法がわかりません。 SPARC でCのライブラリかなにかあるでしょうか? どうかよろしくおねがいします。

みんなの回答

noname#11476
noname#11476
回答No.3

基本的には、その程度の差は当然発生するものとして考えて、それでも問題が起きないようなプログラムにするのが普通です。 他のPG..PGってなんでしょうか?プログラムということですか? コンパイラやライブラリが異なれば異なる可能性があり、Cの規約でもそこまでの再現性は求めていないので、バージョンによって異なってしまうなどいろんなことが起きるでしょう。 もっともよく使われる方法は、最終的に利用するときに有効桁数を決めてそこで四捨五入してしまうことです。 そうしないとまず可搬性のない、トラブルメーカーのソフトになると思います。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

元のプログラムが何をしているかわからなくて、具体例も1個しなかい状況では、汎用的な変換方法などを見つけ出すのは不可能だとおもいます。LSBから1を引けばいいのか、LSBを0にすればいいのかさえわかりません。 もっと大量の例が得られるなら、法則性を導くことはある程度は可能かもしれません。しかし、それとて、その例の範囲で適用できるというだけで、適用できない例外が出てこない保証もありません。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

> printf("1.489 = %08lx%08lx\n", atof((double)???)); こちらが何をしているのかわかりませんが、それ次第ですね。 浮動小数点の場合、まるめ誤差が避けられないので、等しいかどうかという条件判断は避けるのが普通です。両者の差と元の値との比率がある程度以下かどうかというので判定するほうがいいでしょう。doubleでは仮数部は53bitあるので比率が1/2^50以下かどうかくらいでしょうか。bit数に依存するのはあまりよくないのですが。

yankee5
質問者

補足

> > printf("1.489 = %08lx%08lx\n", atof((double)???)); > こちらが何をしているのかわかりませんが、それ次第ですね。 そうです。何をしているかわからないので、 "1.489"の文字列を 何とかして 3ff7d2f1a9fbe76c の形にしたいのです。 元のPGでは、特殊なことはしていないはずなので、 比率で判断するのではなく、atof 以外の変換関数 もしくは、ある汎用的な定数計算をかますことで上記の値にしたいです。 あと、コンパイルオプション(-fround )も デフォルトのままでお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 浮動小数点の切り捨てで-0.5を-1に。

    こんにちは。 小数点以下を切り捨てたいときにキャストするために 以下のようにしたところ、 float  i ; for( i=-2.5f; i<3.5f; i+=1.0f ) {   printf( "%f %d\n", i, (int)i ) ; } -2.500000  -2 -1.500000  -1 -0.500000  0 0.500000  0 1.500000  1 2.500000  2 上記の様な結果になりましたが、これを -2.500000  -3 -1.500000  -2 -0.500000  -1 0.500000  0 1.500000  1 2.500000  2 のように-0.5なら-1にするようしたいのですが、 if文は使わずに計算だけで変換することは 可能でしょうか ?

  • 文字列をfloatで読み込む(atoi,sscanf)。しかし、値がおかしい。

    お世話になっています。 C言語の質問です。 文字列をfloatで読み込もうとしているのですが、出力結果がおかしくて困っています。 文字列をatofで変換した場合、doubleでは上手く表示できるのですが、floatでは少数が上手く表示できません。 また、sscanfでも試したのですが、上手く表示できませんでした。 どうしても、doubleを使わずにfloatであらわしたいと考えています。 どうかこのプログラムの問題点のご指摘お願いします。 実行結果 53.196600 53.196602 53.196602 ソース #include<stdio.h> #include<stdlib.h> #include<string.h> main() { char str[100]="53.1966"; double b; float c,d; b = atof(str); printf("%f\n",b); c = (float)atof(str); printf("%f\n",c); sscanf(str,"%f",&d); printf("%f\n",d); } 開発環境 windowsXP cygwin

  • 浮動小数点数が表示されないんです…。。。

    研究でC言語を使わないといけないんですが、簡単な小数点の表示すらうまくできないんです。誰か助けてください。プログラムの内容はinput.gridというファイルから各変数の値をfscanf関数で読み込み、画面に表示するというごく単純なものでコンパイル、リンクはうまくいくのですが、実行のときにfloating point not loadedと画面に表示され途中で処理が終わってしまいます。同じような経験されたかたいらっしゃいますか?なんとかならないでしょうか??下にプログラムと入力データを記述しておきます。 ・プログラム #include<stdio.h> #include<stdlib.h> main() { int *type; int *t; int *n; double *x; double *y; double *z; double *u; double *v; double *w; double *p; double *rho; FILE *fp_grid,*fp_press ; /*ファイルポインター*/ if((fp_grid=fopen("input.grid","r"))==0){ printf("file not open \n"); exit(1);} if((fp_press=fopen("input.press","w"))==0){ printf("file not open \n"); exit(1);} fscanf(fp_grid,"%d",&t); fscanf(fp_grid,"%d",&n); fscanf(fp_grid,"%f %f %f %f %f %f %f %f",&type,&x,&y,&z,&u,&v,&w,&p,&rho); printf("check\nt=%d,n=%d\n",t,n); printf("%d %f %f %f %f %f %f %f %f",type,x,y,z,u,v,w,p,rho); fclose(fp_grid); return; } 入力データinput.grid 0 21170 0 0.700000 -0.100000 -0.070000 0.000000 0.000000 -0.019927 0.000000 1000.000000

  • C++の打切り誤差についてお聞きしたいのですが・・

    ↓のプログラムが、なぜ実行結果のsumが1ではなく1.000054や9.99999999999906e-001、9.9999999999990619e-001といった答えにになってしまうのでしょうか? 10000のところを512でやった場合は普通に1と出力されたのに・・・ #include <stdio.h> int main(void){ int i; float f; double d; f = 0.0; for(i = 0; i<10000; i++) { f += 1.0/10000; } printf("float: n=%d sum=%f\n", 10000, f); d = 0.0; for(i = 0; i<10000; i++) { d += 1.0/10000; }// end for printf("double:16.14e: n=%d sum=%16.14e\n", 10000, d); printf("double:18.16e: n=%d sum=%18.16e\n", 10000, d); return 0; } 実行結果 float: n=10000 sum=1.000054 double:16.14e: n=10000 sum=9.99999999999906e-001 double:18.16e: n=10000 sum=9.9999999999990619e-001 続行するには何かキーを押してください . . .

  • 浮動小数点数の float型 での最少値について調べています。

    浮動小数点数の float型 での最少値について調べています。 「Visual C++ 2008 Express Edition」の「float.h」の中には、    #define FLT_MIN     1.175494351e-38F   /* min positive value */    #define FLT_MIN_EXP  (-125)           /* min binary exponent */ という記述があります。 float型で表現できる最少値が「1.175494351e-38F」なのだろうと思い、 下記のように 2^-125 を計算してみました。    printf("結果は、「%e」です。", pow((double)2, (double)(-125))); 実行結果は、    結果は、「2.350989e-038」です。 となり、「float.h」の「FLT_MIN」には一致しませんでした。 試しに、下記のようにしてみると( 2^-125 を 2^-126 に変えてみました )    printf("結果は、「%e」です。", pow((double)2, (double)(-126)));    結果は、「1.175494e-038」です。 となって「float.h」の「FLT_MIN」と「ほぼ一致」しているように見えます。 float型での最小値(FLT_MIN)を計算する際に「float.h」での「FLT_MIN_EXP」を使って    2^-125 とするのは間違っているのでしょうか?

  • 浮動小数点エラー

    #include<stdio.h> main (){ float D[5][6] = { {0,0,151.9058382,111.8925551,238.1626765,145.6362657},   {0,151.9058382,0,256.9532465,317.3522119,232.5861795}, {0,111.8925551,256.9532465,0,181.0294098,114.6471}, {0,238.1626765,317.3522119,181.0294098,0,93.41311845} ,   {0,145.6362657,232.5861795,114.6471,93.41311845,0}, };   float data[100][100] ; int n=5; float sum; int i,l; for(i=1;i<=n-2;i++) { sum=0; for(l=i+2;l<=n;l++) { sum=sum+D[i][l]; } ◎ data[i]=D[i][i+1]/(sum/(n-(D+1)));  ←この行 } for (i=1;i<=n;i++){ printf("%f",data[i]); } return (0); } 上のプログラムで、◎の行に浮動小数点の不正な使用とエラーがでてしまいます。 参考書、ヘルプで調べたもののなぜエラーとなるか分かりませんでした。 解決できますでしょうか?

  • プログラムがうまくいきません。教えてください。

    プログラムがうまくいきません。教えてください。 #include <stdio.h> int main(void){ int a, b, c, d, f; printf("国語="); scanf("%d", &a); printf("算数="); scanf("%d", &b); printf("理科="); scanf("%d", &c); printf("社会="); scanf("%d", &d); f = ((a>90)?1:0)+((b>90)?1:0)+((c>90)?1:0)+((d>90)?1:0); printf("\n合計[%d],平均[%.2f]\n",(a+b+c+d),((double)(a+b+c+d)/4.0)); printf("国語[%d],[%.3f%%],[%d]\n",a,((double)a/1.5),((a>90)?1:0)); printf("算数[%d],[%.3f%%],[%d]\n",b,((double)b/1.5),((b>90)?1:0)); printf("理科[%d],[%.3f%%],[%d]\n",c,((double)c/1.5),((c>90)?1:0)); printf("社会[%d],[%.3f%%],[%d]\n",d,((double)d/1.5),((d>90)?1:0)); printf("総合判定[%d],\n", ((f>=3)?1:0)); return (0); } と入力したのですが、実行結果の国語から社会までの[]部分を上下揃えたいのですが揃いません。このプログラムにどのようなことを追加すれば揃えることができますか?教えてください!

  • 型変換がうまく出来ない

     今晩は、Cの初心者です、宜しくお願いします。  下のようなコードを書きましたが、正常に表示されません。  一体何処が悪いのでしょう。 =========================================================== #include <stdio.h> #include <string.h> #include <ctype.h> int main(void) { char s2[20] = "0.789"; double ddt = atof(s2) ; printf("ddt = %lf\n\n" , ddt); printf("atof(s2) = %lf\n\n" , atof(s2)); printf("(float)idt + atof(s2)) = %lf\n\n" , ((float)idt + atof(s2))); return 0; }

  • 実行結果を倍精度浮動小数点数(double)で表示させたいです

    C言語の勉強をしている大学生です。 プログラミングをしている中で、質問が3つほど出てきました。 互いに関連しているのでまとめて質問させてください。 無限等比級数を計算するプログラムを作成しました。 これをコンパイルして実行すると、double型で定義しているのに 小数点以下7桁となってしまいます。 doubleは15桁ということなので、15桁で出力したいのです。 これが1つめの質問です。 <実行結果> input n:10 1.500000 1.750000 1.875000 1.937500 1.968750 1.984375 1.992188 1.996094 1.998047 pow関数がmath.hに含まれているのかも定かではなく、 インターネットでmath.hというものがあると書いてあったので、 インクルードしてみましたが、これは適切でしょうか? これが2つめの質問です。 最後になりますが、インターネットで多倍長ライブラリというものが あるということを知りましたが、この使用方法がわかれば具体的な例を 挙げながら教えていただきたいと思います。 ------------------------------------------------------------ #include <stdio.h> #include <math.h> int main(void) { int n; int i; double total; printf("input n:"); scanf("%d",&n); if (n<1){ printf("unable\n"); return 0; } for(i=1; i<n; i++){ total += 1.0 / pow(2.0,i); printf("%f\n",total+1.0); } } ------------------------------------------------------------

  • VC6における浮動少数点数値について

    はじめて質問させて頂きます。 C言語の基礎演習レベルの題材ですが 想定外の結果が表示され解決できておりません。 内容としては2つのfloat型変数(以下ソースのb,c)に 全く同じ演算処理結果を代入し コンソール表示させるというプログラムです。 #include <stdio.h> void main() { float a = 0, k = 0; float b = 0; float c = 0; a = 0.2; k = 20.0; k += a; b = k - 20.0; c = k - 20.0; printf( "%f %f %f %f\n", a, b, c, k ); if( b == c ) { printf( "*\n" ); } while( getchar() != EOF ){} } 予想実行結果: 0.200000 0.200000 0.200000 20.200000 * 実際の結果: 0.200000 0.200000 0.200001 20.200001 当方、浮動少数点数値の扱いにも不慣れな為、原因不明です。 なぜこのような結果になるのか、どなたかご教授頂けないでしょうか。 宜しくお願い致します。