質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.03%

C言語の浮動小数点数の範囲について

受付中

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 1,098

mofu_mofu

score 71

みなさんいつもお世話になっております。

Float型とDouble型の(符号仮数指数の)範囲について疑問があるので質問をさせていただきます。

参考書に

Floatは4byte +-1.1E-38 ~ +-3.4E+38
Doubleは8byte +-2.2E-38 ~ +-1.7E+308


と書いてあったのですが、この記載の

Floatは4byte +-1.1E-38 ~ +-3.4E+38

の範囲を分解すると

-1.1E-38 ~ +1.1E-38
-3.4E+38 ~ +3.4E+38

の二つの範囲を取りうるのでしょうか?(Doubleも然り)

そうだとすると、「なんで二つの範囲があるんだろう?範囲が二つあるなら逆にわかりづらそう」って思ってしまうのですがこの理由を教えていただけないでしょうか。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

+4

K.I.S.S.

Floatの範囲

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+3

まず、C言語自体では浮動小数点数の範囲は決まっていません。もっとも、パソコンのC言語処理系ではIEEE 754の2進法記法が採用されることがほとんどなので、以下ではそれを前提に考えます。

そして、浮動小数点数は、「符号」「仮数」と「指数」の3つの要素からなっています。マイナスの値は符号だけ反転すればいいのですが、指数を小さくできる量にも限界があるので、絶対値の小さな方にも限界があります。

なので、「+-1.1E-38 ~ +-3.4E+38」は「-1.1E-38 ~ +1.1E-38」と「-3.4E+38 ~ +3.4E+38」ではなく、「-3.4E+38~-1.1E-38」と「±0」と「+1.1E-38~+3.4E+38」というような範囲となっています(0だけは別枠で用意してあります)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

たとえば「Floatは4byte +-1.1E-38 ~ +-3.4E+38」とは、

Floatは
-3.4E+38 ~ -1.1E-38
0.0
+1.1E-38 ~ +3.4E+38
という範囲の数が扱えるという意味です。
1.1E-38より(絶対値が)小さな数はゼロに丸められるか切り上げられて±1.1E-38になるかです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

記述しているのは、たんにとり得る数値の範囲なのでは?

最小値と最大値を書いてるだけだと思いますが

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/12 11:55

    y_waiwaiさん
    お世話になります。

    よくわかっていないのであまり要領を得ていないトンチンカンな返信になってしまい恐縮なのですが、
    たとえばFloatであれば、符号に1bit 仮数に23bit 指数に8bitが割り振られていて、全体で32bit(4byte)ですが、
    それなら「仮数部は23bitで取りうる範囲の値2^23 = 8388608通りの任意の範囲を表すことができます」
    「指数部は8bitなのでで取りうる範囲の値2^8 = 256通りの任意の範囲を表すことができます」
    という風に記述するのかな?と思いました。

    わざわざ仮数部を+-1.1指数部を+-38というように1.1や38と明記している理由ってなんだろう、というのが疑問です。

    よろしくお願いいたします。

    キャンセル

  • 2018/03/12 11:57

    「1.11111111111111111111111(2進)×2^128」なんて書かれても人間には値の範囲が把握できないので、10進法に換算してあります。

    キャンセル

  • 2018/03/12 11:57

    「浮動小数点とは」とかなんとかで、まずはぐぐってみましょう。
    そんでそこにたくさん解説が出てくると思いますので、まずはそれを読んでみることです

    そうすれば、あなたの書いていることが的はずれだ、とわかるとおもいます

    キャンセル

  • 2018/03/12 12:07

    改めて調べ直し整理し直してから返答させていただきます。ありがとうございます。

    キャンセル

0

その参考書は誤解を招きやすい書き方をしていますね。浮動小数点で表せる数値の範囲は、通常は「絶対値」で考えます。つまり、floatでは絶対値の最小値が1.1E-38、最大値が3.4E+38ということです。

浮動小数点は内部では2進数で扱っているので、10進数とはうまく合致せず中途半端な数値になることを頭に入れておかないといけません。

判りやすいように仮数4bit・指数3bitとして最大値と最小値を表すと

1111000.0  → 10進で78
0.00000001 → 10進で0.00390625

となります(たぶん)。見ての通り、整数側と小数側で全く違った値になってしまっています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Floatは4byte +-1.1E-38 ~ +-3.4E+38

これは下記を意図したものです。

Floatは4byte ±1.1E-38 ~ ±3.4E+38

復号同順というやつ。なので、あなたの解釈は誤り。

より正確には、

Floatは4byte 約±1.1E-38 ~ 約±3.4E+38 および 0 および ±∞ および 非数(NaN)

ですね。
他の方の回答にありますが、C言語の規格の話じゃなくて、メジャーな処理系の実装の話です。

注:もうすこし有効数値を長くすると、約±1.175E-38 ~ 約±3.402E+38 なので、「約±1.1E-38」とすべきか「約±1.2E-38」とすべきか難しいところです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る