![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
コンパイラはMicrosoft visual C&C++を使用しています。
(1)型指定子のfloat,doubleの大きい数値について。
計算をするとfloatは7桁までは正しくて、7桁より大きい桁はデタラメです。doubleは15桁までは正しくて、15桁より大きい桁はデタラメです。有効数字7桁,15桁とはこういうことでしょうか。
後、floatは有効数字7桁、doubleは有効数字15桁で本当に正しいのでしょうか。
(2)型指定子のfloat,doubleの小数点以下の数字について。
floatは10^-38まで、doubleは10^-308までの数字を扱えると参考書には書いてありますが、計算をしますと小数点以下6桁までは求まりますが、それ以下は求まりまりません。それ以下の数値はすべて0になります。なぜでしょうか。
(3)int,long intとdouble long doubleの違いについて。
intとlong intはともに-2147483648~2147483647までの範囲だと思います。またdoubleとlong doubleはともに有効数字15桁でした。何か違いがあるのでしょうか?
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
まだ出ていない内容だけ回答します。
> intとlong intはともに-2147483648~2147483647までの範囲だと思います。またdoubleとlong doubleはともに有効数字15桁でした。何か違いがあるのでしょうか?
C++では、仮に精度や符号の有無などの特性が同じであっても、あくまでも別の型として扱われます。具体的には、多重定義やテンプレートの解決の際に、型の違いが活きてきます。
C++の型は、ある意味で値と同じぐらいの意味を持ちます。
No.3
- 回答日時:
>計算をするとfloatは7桁までは正しくて、7桁より大きい桁はデタラメです。
>doubleは15桁までは正しくて、15桁より大きい桁はデタラメです。
デタラメではありません。「表現可能な範囲での、最も近い値」です。
>(1)型指定子のfloat,doubleの大きい数値について。
IEEE 754-2008の規格に沿った4バイトfloat、8バイトdoubleの場合、仮数部のビット数はそれぞれ24ビット、53ビットです。指数部はそれぞれ8ビット、11ビットです。
floatの仮数部が24ビットの場合、表現出来るのは「(0~2の24乗-1)×(2のn乗)、但しnは-126~+127」です。
doubleの仮数部が53ビットの場合、表現出来るのは「(0~2の53乗-1)×(2のn乗)、但しnは-1022~+1023」です。
floatの場合の「2の24乗-1」は「16777215」ですから、実質的に「0~9999999に、2のn乗を掛けたもの」しか表現できません。つまり「10進数で7桁だけ」が有効です。
doubleの場合の「2の53乗-1」は「9007199254740992」ですから、実質的に「0~999999999999999に、2のn乗を掛けたもの」しか表現できません。つまり「10進数で15桁だけ」が有効です。
>(2)型指定子のfloat,doubleの小数点以下の数字について。
floatで「2の10乗」と「2の-10乗」を足し算するとどうなるでしょうか?
まず、指数と仮数に分けます。「1×2の10乗」と「1×2の-10乗」になります。
次に、指数部を同じにしないと、足し算出来ません。
指数部が小さい方を大きい方に合わせる為「1×2の-10乗」の仮数部を2の20乗で割って、指数部に20を加算します。
「1×2の-10乗」と「0.5×2の-9乗」が等しいのは判りますね。
1を2の20乗で割ると0.00000095367431640625です。-10に20を足すと10です。従って「1×2の-10乗」は「0.00000095367431640625×2の10乗」になります。
2つの数値が「1×2の10乗」と「0.00000095367431640625×2の10乗」になれば、指数部が同じですから、仮数部を足し算できます。
結果「1.00000095367431640625×2の10乗」になります。
これを2進数で書くと以下のようになります。
1.00000000000000000000×2の10乗
+)1.00000000000000000000×2の-10乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
??????????????
↓
指数部が違うので、指数部を同じにする。
↓
1.00000000000000000000×2の10乗
+)0.00000000000000000001×2の10乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
1.00000000000000000001×2の10乗
この計算が可能なのは「仮数部が24ビットあったから」です。
では、floatで「2の13乗」と「2の-13乗」を足し算するとどうなるでしょうか?
先ほどと同様に、2進数で書くと以下のようになります。
1.00000000000000000000000000×2の13乗
+)1.00000000000000000000000000×2の-13乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
??????????????
↓
指数部が違うので、指数部を同じにする。
↓
1.00000000000000000000000000×2の13乗
+)0.00000000000000000000000001×2の13乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
1.00000000000000000000000001×2の10乗
この足し算の結果をfloatの値にすると、仮数部は24ビットなので、上から24ビットだけが残り、25ビット目以降は「消えて無くなって」しまいます。
と言うより、足し算する前に「仮数部が足りなくて、足す数がゼロになってしまう」のです。
先ほどの2進数の加算で、仮数を24ビットにすると、以下の[]の中身は「精度不足で無くなってしまう」のです。
1.0000000000000000000000[0000]×2の13乗
+)1.0000000000000000000000[0000]×2の-13乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
??????????????
↓
指数部が違うので、指数部を同じにする。
↓
1.0000000000000000000000[0000]×2の13乗
+)0.0000000000000000000000[0001]×2の13乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
??????????????
↓
仮数が24ビットなので[]の中身が消えてしまう。
↓
1.0000000000000000000000×2の13乗
+)0.0000000000000000000000×2の13乗
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
1.0000000000000000000000×2の13乗
求まる答えは「ゼロを加算した値」です。
つまり「大きい値に小さい値を足したり引いたりしても、アンダーフローして、ゼロを足したり引いたりしてしまう」のです。
>(3)int,long intとdouble long doubleの違いについて。
>intとlong intはともに-2147483648~2147483647までの範囲だと思います。
それは「intもlong intも、符号1ビット+数値31ビットの、32ビット整数」と仮定した時だけです。
「符号1ビット+数値31ビット」と仮定した時、2の31乗は2147483648なので、正は「1×2の31乗-1」、負は「-1×2の31乗」まで、つまり「-2147483648~2147483647」の範囲を表現できます。
この「数値31ビット」は、float、doubleの「仮数部○○ビット」に相当します。
前述の有効桁数の部分で書きましたが、以下のようになります。
floatの場合「2の24乗-1」は「16777215」です。つまり「10進数で7桁」です。
doubleの場合「2の53乗-1」は「9007199254740992」です。つまり「10進数で15桁」です。
int、long intの場合「2の31乗-1」は「2147483647」です。
すべて「2進数で考えて」下さい。「ホゲホゲ×2のホニャララ乗」が基本です。
この回答への補足
ご回答ありがとうございました。
(1),(3)については分かりました。
(2)についてもう一度お伺いしたいのですが、私が計算した値はとても大きい数ととても小さい数ではなくて10^-8程度の値どうしの演算でした。もう少し正確に言いますと。0.000000という答えでした。
足した値が0になってしまうということではなくて、答えが0.000000になってしまうという状況なのですが、よろしければご回答よろしくお願いします。
No.2
- 回答日時:
(1)
floatは4バイト、doubleは8バイト
このうち符号、実数部、指数部にビットを割り当てているため
値として持つのはfloatは23bit、doubleは52bitなので
自然と有効桁数は限られます。
(2)
1.024 => 1.024 x 10^0
1024. => 1.024 x 10^4
この違いは指数(10の何乗)だけですよね?
この指数というのが、floatの場合±38、doubleの場合±308ってだけなんです。
だから有効桁数を越えるとすべて0になるのですね。
No.1
- 回答日時:
(1)sizeof(float)やsizeof(double)の値、つまり、
float型やdouble型のために何バイトの領域を割り当てているかによって、
有効数字の桁数は違ってきます。
(2)どんな計算をしましたか?そのときのソースコードを正確に提示してください。
(3)sizeof(int)とsizeof(long int)が同じならば、
int型とlong int型で扱える数値の範囲は同じです。
doubleとlong doubleの関係も同様です。
この回答への補足
回答ありがとうございました。
(2)についてですが以下のようなプログラムを書きました。
#include <stdio.h>
int main()
{
float a,b;
printf("a+b,a-bの計算を行うプログラム。\n");
scanf("%f %f",&a,&b);
printf("a+b=%f,a-b=%f\n",a+b,a-b);
}
a,bの値に0.000000033556 0.000000012556という値を入力したところ
a+b=0.000000 a-b=0.000000という答えでした。
floatをdoubleに変えても同様の答えでした。
ぜひ回答よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# C++で割り算の結果を昇順に出力するプログラムを作りたいのですが、例えば(double)100000 3 2022/07/15 17:46
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- Visual Basic(VBA) VBAでのMATCH関数 3 2022/10/17 19:06
- C言語・C++・C# (C言語)めちゃくちゃな値になってしまいます。 5 2022/08/13 11:55
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# C言語のマクローリン展開ローラン展開のコードについて 3 2022/12/15 14:45
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
P値(統計学)を求めるプログラム
-
プログラムでの数字につく”f”の...
-
C++で外積
-
指数の表示
-
Cで3乗根を求める方法
-
VS2010_C#(Win7)で符号付指数文...
-
long doubleの表示方法
-
Cプログラミングの問題です。ニ...
-
C言語を実行すると-infが出てき...
-
カウントアップタイマ
-
C言語について(三角形の面積・d...
-
型指定子についての教えてくだ...
-
型変換のitoaのaって?
-
C言語の構造体の問題が分かりま...
-
C言語の乱数生成について。 0〜...
-
VisualC++2005にてerror C2664...
-
C言語
-
C言語のプログラムで#include<m...
-
C 開放してるのにエラー(doubl...
-
待ち行列シュミレーションのプ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
doubleの変数にintとintの割り...
-
float型とdouble型の変数の違い...
-
c言語で、繰り返し文の中で、0....
-
C言語を実行すると-infが出てき...
-
C言語 関数プロトタイプ宣言の...
-
C 開放してるのにエラー(doubl...
-
C言語の型による処理速度の違い
-
至急です! マクロ定義で #defi...
-
関数におけるif文とreturn文に...
-
c言語のプログラミングについて...
-
2分法で方程式の複数の解を自...
-
-1.#IND00と出てしまうのですが...
-
doubleは常に%lfとするべきなのか
-
C言語のpow関数の不具合
-
C言語で-23乗を取り扱うには
-
C言語で台形公式を使った二重積...
-
Cで3乗根を求める方法
-
sin(x)の近似について
-
2次方程式の解を求めるプログ...
おすすめ情報