
何度もすみません。C言語についてのご質問です。
以下のソースコードを作成してコマンドプロンプトで実行したところ、下の実行結果のようになりました。double型から無理やりint型にしたので値が変わってしまうのはわかりますが、今回の場合は少数切り捨てで「7」になるはずですよね?
ものすごい大きい値になってしまったんですけど、何故こうなってしまったのでしょうか?
[ソースコード]
#include <stdio.h>
int main(){
int a=2017;
double b=7.16;
printf("a=%d, b=%d\n", a, b);
printf("a=%d, b=%f\n", a, b);
printf("a=%f, b=%f\n", a, b);
return(0);
}
[実行結果]
a=2017, b=171798692
a=2017, b=7.160000
a=0.000000, b=7.160000
No.5ベストアンサー
- 回答日時:
>普通ならdouble型を無理やり整数型に直したら小数点以下が切り捨てで表示され、今回のbなら[7]となるはずだと思うのですが、何故全然違う値である[171798692]となってしまったのでしょうか?
ptinfの関数の場合、そのままの値が引数として渡されます。
double b=7.16;
printf("b=%f\n",b);・・・①
printf("b=%d\n",b);・・・②
①の場合でも、②の場合でも、bの内容がそのままprintfに渡されます。
printfは①の場合、その値をdouble型のデータと解釈して、表示します。
printfは②場合、その値をint型のデータと解釈して、表示します。
そのために、171798692が表示されます。
以下のプログラムを実行すると、それが理解できるかと思います。
--------------------------------------------------------
#include <stdio.h>
#include <string.h>
int main(){
double b=7.16;
int z[2];
double c;
memcpy(z,&b,8);
memcpy(&c,z,8);
printf("b=%f\n",b);
printf("b=%d\n",b);
printf("z[0]=%d, z[1]=%d\n", z[0],z[1]);
printf("c=%f\n", c);
return(0);
}
--------------------------------
実行結果
b=7.160000
b=171798692
z[0]=171798692, z[1]=1075618775
c=7.160000
No.4
- 回答日時:
printf("a=%d, b=%d\n", a, (int)b);
printf("a=%d, b=%f\n", a, b);
printf("a=%f, b=%f\n", (double)a, b);
こんな風に、書式に合わせて値が変換されることを期待しているかと思いますが、実際にはそうなりません。
printfのようなC言語の可変長引数(引数の数が固定ではない)関数には、ちょっとややこしい仕様があります。
その一つが、呼び出し側で指定した引数の型と数が、関数側に伝わらない、というのがあります。
printfでは、書式文字列中の%〜で、型と数を取得します。
printf("a=%d, b=%d\n", a, b);
を例にすると
int: 32ビット
double: 64bit として。
呼び出し側で
引数1: 文字列("a=%d, b=%d\n"へのポインタ
引数2: aの内容の32bitのビットパターン
引数3: bの内容の64bitのビットパターン
と設定してからprintfを実行します。
printf側では
引数1を解析して、
最初の%d
→
・引数2から
・書式がdだから 32ビット取ってきてintだと解釈する
次の%d
→
・引数3から
・書式がdだから 32ビット取ってきてintだと解釈する
と動作します。
あくまで、ビットパターンなので、2番目の%d に
(double) b /* 小数の切り捨て */
の変換が実行されるわけではなく、
*((int *) & b)
と同等のことが起っています。
printf("a=%f, b=%f\n", a, b);
では逆に、32ビットしかないaに32ビットのよくわからないビットを加えたものをdoubleと解釈したものです。
多分、0.000000(この後に0でない値が出てくる)と解釈されたのでしょう。
詳細は、環境によって違ってくる場合があります。
※ aの32ビット+bの先頭32ビット 、 bの後半32ビット+よくわからない32ビット となることもあるでしょう。
コンパイルスイッチで警告レベルを上げると、%と変数の型の違いを警告してくれることがあります。
ですが、基本的に「そこはプログラマがちゃんと合わせろ」というのがC言語の考え方です。
なるほどです。プログラミングしていくうえでは気を付けないといけないことなんですね。
大変参考になりました。ご回答、本当にありがとうございました。
No.3
- 回答日時:
自分の質問に「ご質問」となるのは変なんですが…
まぁそれはさておき。
unsigned char *c=(unsigned char *)&b;
printf("b(HEX)=%02X%02X%02X%02X%02X%02X%02X%02X\n", *(c), *(c+1), *(c+2), *(c+3), *(c+4), *(c+5), *(c+6), *(c+7));
のようにして、
double bがメモリ上にどのように格納されているか見てみます。
b(HEX)=A4703D0AD7A31C40
となりました。(手元ですぐに確認できる環境がUbuntu 22.04の64Bitだった)
%dで扱う場合、ここから(おそらく32Bit)取ってくるので…
0xA4, 0x70, 0x3D, 0x0Aのバイト列をリトルエンディアンの数値として扱います。
0A3D70A4hになります。10進数表記に変換すると…171798692になりますね。
ということで、別におかしなことはないです。
「引数として渡すときにint型に変換される」のであれば、7になるでしょうけど、double型のままであれば上記の実験の通りでしょう。
No.2
- 回答日時:
ごめんなさい、質問を読み違えてました。
(C++) | ブラウザでプログラミング・実行ができる「オンライン実行環境」| paiza.IO
https://paiza.io/projects/eUdqdut4TW4Gmg20a5_GxQ …
↑
ココで試してみたところ、
printf("a=%d, b=%d\n", a, b);
は毎回違う結果を吐きました。マイナス値も。
知識のある方からの回答をお待ち下さい。失礼しました。
No.1
- 回答日時:
この記事で解決。
↓
【C言語】小数点以下の桁数を指定する方法【printf】 | MaryCore
https://marycore.jp/prog/c-lang/format-floating- …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# 3×3のラテン方陣をつくるプログラムを作成したのですが、(↓) #include <stdio.h> 5 2023/07/10 01:53
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# プログラミングペーパーテスト 次の問題の実行結果を答えろ #include int x[ ] = { 1 2022/06/16 21:49
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
High-performance Embedded Wor...
-
c言語
-
CPU温度・負荷等を調べるには
-
C言語の数値入力
-
このプログラムの実行結果につ...
-
カレンダーのプログラムについて
-
*を使ったジグザグのラインをプ...
-
C言語 (ラックナンバー)
-
c言語でAからZまでを表示する...
-
C言語のプログラミングです 以...
-
boolean型の戻り値は可能か
-
初心者です。C言語でクイズを作...
-
パスカルの三角形についてのCプ...
-
wsprintfの書式制御文字列につ...
-
ピラミッド表示プログラム。
-
再帰呼び出しで求めたい経路を...
-
コンパイルエラーの原因が解ら...
-
printf で二進表示を行いたい。
-
C言語についてです学籍番号、名...
-
10個出力で改行したいのですが...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
コマンドラインに出力した文字...
-
(C言語)めちゃくちゃな値にな...
-
c言語でAからZまでを表示する...
-
printfの出力内の文字をdefine...
-
defineで定数が置き換えられな...
-
c言語で2000年以降カレンダーを...
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
4の倍数を論理演算で表す。。
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
教えてください!!
-
Cプログラムについて
-
サイコロをふって、出た目のパ...
-
strcmp
-
じゃんけんゲームの応用
-
C言語でマウス入力(クリックや...
-
printfの有無で値が変化する
おすすめ情報
ごめんなさい。bについてのご質問です。
ご回答ありがとうございます。添付先のサイトを拝見しました。
%7.2fや%6.3fみたいな形で少数型の数字の桁数の調整ができることは存じ上げておりますが、今回の場合、[7.16]と[171798692]は全く違う数だと思うんですよ。
普通ならdouble型を無理やり整数型に直したら小数点以下が切り捨てで表示され、今回のbなら[7]となるはずだと思うのですが、何故全然違う値である[171798692]となってしまったのでしょうか?
私の理解力不足でしたら申し訳ないです。
理解できました。皆様、ご回答ありがとうございました。