• ベストアンサー

C言語イプシロン値

現在使用中の開発環境(C言語使用)標準ヘッダfloat.hに単精度浮動小数点数イプシロン値が下記のように定義されています。 #define  FLT_EPSILON   0x8p-26F 「0x8p-26F」なる表現を初めて見たのですが、これはどういう意味で、具体的にどんな数字になるのでしょう? ご存じの方、教えてくださいませ。 よろしくお願いします。

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

  • ベストアンサー
  • asciiz
  • ベストアンサー率70% (6628/9391)
回答No.3

「0x8」-- 16進数の8 「p」-- 指数表記 「-26」-- 2の-26乗 「F」-- float 型 という、指数表現です。 この値は、1.0と、その次に大きい最少の小数値との差を、示しています。 いわば「floatで表現できる最少差分」といった意味になるでしょうか。 ---- 8なら8と書けばいいのに何でわざわざ0x8なんて書いてあるかというと。 「16進数の」指数表現ってところにポイントがあると思います。 >浮動小数点数の内部表現(IEEE) >https://www.k-cube.co.jp/wakaba/server/floating_point.html 32ビットfloatのバイナリ表現は、上記ページのようになっています。 0x8 とは、二進数で書くと 0b1000。※ 0b は2進数プレフィックス そして2のマイナスn乗っていうのは、マイナス1つごとに1/2する、それをコンピュータ処理的に言うと、「nビット右シフトする」に相当します。 例) 8÷2=4 を2進表現すると 0b1000 ÷ 2 = 0b0100。1桁右にずれている すなわち 0x8p-26F という浮動小数点値のビット列は、以下の並びになります。 [0000 0000 0000 0000 0000 0000 0000 0001] 符号0(プラス)、指数部000 0000 0(最少値=-127乗)、仮数部 000 0000 0000 0000 0000 0001(表現できる最小の数)。 これは紛れもなく、このfloat形式でで表現できる最少の差分値というわけなのです。

black2005
質問者

お礼

ご回答ありがとうございます。 何と親切でわかり易い回答なんでしょう・・・ お陰様で良く理解できました。 感謝致します。

その他の回答 (4)

  • f272
  • ベストアンサー率46% (7995/17088)
回答No.5

あとで見た人が混乱しないように書いておくと [0111 1111 1000 0000 0000 0000 0000 0000]=1 [0111 1111 1000 0000 0000 0000 0000 0001]=1+2^(-23) ですから,1.0とその次に大きい最小の小数値との差は2^(-23)です。 [0000 0000 0000 0000 0000 0000 0000 0000] は非正規化数であり+0です。また [0000 0000 1000 0000 0000 0000 0000 0000]=2^(-126) は最小の正の数であって,1.0とその次に大きい最小の小数値との差ではありません。実際,1+2^(-126)を表現しようとしても [0111 1111 1000 0000 0000 0000 0000 0000 ...ずっと先の方で1] にしかできませんから32bitでは表現できません。。

black2005
質問者

お礼

補足ありがとうございました。 う~ん、難しいですね・・・ 少々混乱してきました^^; これから色々と勉強して理解致します。

  • asciiz
  • ベストアンサー率70% (6628/9391)
回答No.4

すみませぬNo.3は間違いかも ビット列で考えて仮数部最小の数値は、オール0の [000 0000 0000 0000 0000 0000] なので、表現できる最小数はやはり全ビット0の [0000 0000 0000 0000 0000 0000 0000 0000] になって、10進数表現では 1.0×2^-127 が最少の差分値ってことに…?(汗

black2005
質問者

お礼

補足ありがとうございます。 ”差分”なので0ではなく、値を持つ最小値ではないのでしょうかね? なので、回答3で良いような・・・ 良くわかりませんけど^^;

  • f272
  • ベストアンサー率46% (7995/17088)
回答No.2

https://cpprefjp.github.io/lang/cpp17/hexadecimal_floating_literals.html 0x...十六進プレフィックス 8...仮数部(十六進整数) p...指数部(プレフィックス) -...指数部(符号) 26...指数部(十進数) F...サフィックス(float型) つまり0x8p-26Fは8*1*2^(-26)=2^(-23)=1.19209*10^(-7)を意味します。

black2005
質問者

お礼

ご回答ありがとうございます。 記述の意味は良くわかり勉強になりました。

回答No.1

ググれば出てくるだろう? https://ja.cppreference.com/w/cpp/language/floating_literal 8×2^-26 C++17に対応したコンパイラが必要

black2005
質問者

お礼

ご回答ありがとうございます。 ググる際のキーワードがわからなかったんです・・・^^; 早速、リンク先を読ませて頂きます。

関連するQ&A

  • 浮動小数点数の 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 とするのは間違っているのでしょうか?

  • C言語の書き方

    倍精度の浮動小数点で与えられる4点の座標(x1,y1),(x2,y2),(x3,y3),(x4,y4)を入力して、その4点が頂点になる四角形の面積を算出して表示するプログラムのC言語での書き方を教えて下さいm(__)m

  • C言語について

    倍精度の浮動小数点で与えられる4点の座標(x1,y1),(x2,y2),(x3,y3),(x4,y4)を入力して、その4点が頂点になる四角形の面積を算出して表示するプログラムをC言語を用いて書くとどういうプログラムをつくればいいのでしょうかm(__)m

  • c言語の変数の型について

    浮動小数点数の変数の型ってfloat、double、long doubleがありますよね?(その他もあったら教えてください) doubleはfloatの倍精度らしいですが、倍精度ってのは扱える数字の範囲が2倍なのか有効桁が2倍なのかわからないんで教えてほしいです。ちなみに、doubleとlong doubleの違いも判りません。 あと、これらの変数はprintfで出力するときは最高で8桁までしか出力できないんでしょうか?20桁とかは無理なんですかね?

  • PHPでε(イプシロン)のような定数はありますか?

    C言語では、 >1.0 + ε > 1.0 となる最小の値ε >#define FLT_EPSILON 1.19209290E-07F >#define DBL_EPSILON 2.2204460492503131E-16 >#define LDBL_EPSILON 1.084202172485504434e-019L のような形で定義されているそうですが、 PHPにおいてはそのような値は定義されているのでしょうか? そもそも小数点以下を評価(比べる)する際に C言語などと違う点はどこらへんでしょうか?

    • 締切済み
    • PHP
  • float.h のテスト結果がおかしい

     float.h  をテストするため、次のようなプログラムを作りました。  float.h に書かれている値が書き出されると思ったのですが、少し値が違います。  FLT_MAX と DBL_MAX の値が違っています。本当にこのヘッダファイルを読んでいるかと思い、 #define FLT_MAX 3.4e+3f    と変更すれば、 Max= 3.400000000000000000E+03 と出てきます。  一致しない原因は何でしょう。  コンパイラはルネサスのHEWで、CPUはH8/3052です。 *** float.h *** #define FLT_MAX 3.4028235677973364e+38f #define FLT_MIN 1.175494351e-38F #define DBL_MAX 1.7976931348623158e+308 #define DBL_MIN 2.2250738585072014e-308 *** プログラム *** sprintf(str," float :%ldBytes Max= %.18E Min= %.18E\r\n", sizeof(float), FLT_MAX, FLT_MIN) ; Put_str(str) ; sprintf(str," double:%ldBytes Max= %.18E Min= %.18E\r\n", sizeof(double), DBL_MAX, DBL_MIN) ; Put_str(str) ; *** 結果 *** float :4Bytes Max= 3.402823466385288600E+38         Min= 1.175494350822287500E-38 double:8Bytes Max= 1.797693134862315700E+308          Min= 2.225073858507201400E-308 *** まとめて整理 ***  元の原稿は比較し易いように縦に数字が並ぶように書いているのですが、 ここに書き込むとずれてしまいます。 #define FLT_MAX 3.4028235677973364e+38f         Max= 3.402823466385288600E+38  FLT_MIN に比べ有効桁数が多いのが気になる。  同じ有効桁数で区切っても ...567 と ...466 とでは誤差が大きい。    FLT_MAX 3.402823567 7973364e+38f       Max= 3.402823466 385288600E+38     FLT_MIN 1.175494351e-38F #define FLT_MIN 1.175494351e-38F         Min= 1.175494350822287500E-38  四捨五入なら分かる。 #define DBL_MAX 1.7976931348623158e+308         Max= 1.797693134862315700E+308  最後が8と7で違う。しかし、DBL_MAX は8バイトで表せる値に対して四捨五入したために7が8になったと考えれば納得出来る。 #define DBL_MIN 2.2250738585072014e-308         Min= 2.225073858507201400E-308  ピッタリ合っている  宜しくお願いします。

  • データ型について

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

  • C#のキャストについて(32bit浮動小数点)

    こんにちは。 現在、Visual Studio 2005を使用してC#のプログラムを作成しています。 32bitの浮動小数点のデータを表示しようとしているのですがうまくいきません。 具体的な例としては 0x42F6E9E0  → 123.456789 0x4476E9E0  → 987.654321 のように変換した結果を表したいと考えています。 c言語では int main() { int h = 0x42F6E9D5; float f; f = *(float *)(&h); return 0; } のようにすればfで値(123.45678)が取得できたのですが、 これと同じ事をC#ではどのように書くのでしょうか? ポインタを含んだキャストのやり方がわかりません。 以上よろしくお願い致します。

  • 式をC言語で立てれません

    式をC言語で立てれません 式をC 言語で立てれません こんにちは。私は今実験で円板振動子の中心軸上の音圧分布を求めています。 そこで写真のような図をプロットするために与えられた式をC言語で書いています。 式の詳細は P/2ρcV = |sinπ(√(r/λ)^2 + (a/λ)^2)(√はここまで)-(r/λ))| です。 しかしうまくプロットできません。 プログラムは ------------------------------------- #include <stdio.h> #include <math.h> #define F 120 //周波数(Hz) #define C 1500 //音速(m/s) #define A 0.2 // 半径(m) int main() { double x, m, s, p, o, w, l; int i; for (i=0; i<100; i++) { x= (double)i; //観測点までの距離を表しました。距離が変化することで音圧が変わるためです。 l = C/F; //λをlとして音速÷周波数で定義できます。 m = x/l; //x軸です。 o = m*m + (A/l)*(A/l); //式のsinの中身です。 s = sin(M_PI*(sqrt (o) - m)); //sin全体を定義します。 w = fabs(s); //sin全体を絶対値に置き換えます。 p = w; //新しい変数に入れます。 printf("%9.9f %9.9f\n", m, p); } return 0; } ------------------------------ といった感じです。先生からはx軸のプログラムだけいじれば勝手に y軸も出てくるとヒントを頂いているのでx軸についてのプログラムを 書いています。コンパイルはできても写真のようにいきません。 半径やλや周波数はa/λ=2.5と書いてあったので値は推測です。 C言語はあまり得意ではないので困っています。 お分かりになる方、ご教授お願い致します。 ※式が間違っていたので新しく質問します。

  • 式をC言語で立てれません

    式をC言語で立てれません こんにちは。私は今実験で円板振動子の中心軸上の音圧分布を求めています。 そこで写真のような図をプロットするために与えられた式をC言語で書いています。 式の詳細は P/2ρcV = |sinπ(√(r/λ)^2 + (a/λ)^2)(√はここまで)-(r/λ)^2)| です。 しかしうまくプロットできません。 プログラムは ------------------------------------- #include <stdio.h> #include <math.h> #define F 120 //周波数(Hz) #define C 1500 //音速(m/s) #define A 0.2 // 半径(m) int main() { double x, m, s, p, o, w, l; int i; for (i=0; i<100; i++) { x= (double)i; //観測点までの距離を表しました。距離が変化することで音圧が変わるためです。 l = C/F; //λをlとして音速÷周波数で定義できます。 m = x/l; //x軸です。 o = m*m + (A/l)*(A/l); //式のsinの中身です。 s = sin(M_PI*(sqrt (o) - m)); //sin全体を定義します。 w = fabs(s); //sin全体を絶対値に置き換えます。 p = w; //新しい変数に入れます。 printf("%9.9f %9.9f\n", m, p); } return 0; } ------------------------------ といった感じです。先生からはx軸のプログラムだけいじれば勝手に y軸も出てくるとヒントを頂いているのでx軸についてのプログラムを 書いています。コンパイルはできても写真のようにいきません。 半径やλや周波数はa/λ=2.5と書いてあったので値は推測です。 C言語はあまり得意ではないので困っています。 お分かりになる方、ご教授お願い致します。

専門家に質問してみよう