天国にいけるC言語入門 シーズン1 パソコン超初心者がゼロから東方風シューティングをつくる編 ver.0.4.15.790 RELIEF
☆実数値が1つでも計算式中に含まれている場合は計算式の計算結果が整数値になっても%d出力変換指定子でなく%f出力換指定子を使用してください
👇のエピソードで統合開発環境Visual StudioとEAZY IDECでは数値計算結果が異なって表示されます。ですが根本的なコンピュータの数値計算の仕組みは全く同じなのです
☆実数値が1つでも計算式中に含まれている場合は計算式の計算結果が整数値になっても%d出力変換指定子でなく%f出力換指定子を使用してください
☆実数値が1つでも計算式中に含まれている場合は計算式の計算結果が整数値になっても%d出力変換指定子でなく%f出力換指定子を使用してください☆
そのころ、ソーラーが眠るのを見届けたニーモは
好き放題やっていた。
やっぱり妖精さんはみんないたずら好きなんだね。
solarplexuss
ソーラーの前では内側におさえていた光を怒涛のごとく
開放する。
あたりがニーモの光圧で何も見えないほど真っ白に染まる。
ニーモ 「やっぱり、こうでなくっちゃ。」
あたりが光で埋め尽くされ満足げに
微笑むニーモ。
寝ているソーラーをみると
ニーモ 「あっいい場所、みっけ。」
めざとくマイスペースをみつけると
しゅんとニーモは瞬間移動しソーラーの額の上にちょこんとに腰掛ける。
ニーモ 「ここいいわ。楽チン、楽チン^^♪♪♪~ 」
思い切りからだをのばし、
ソーラーの額に手をついて脚をぱたぱたさせてみる。
たっくさん上機嫌で歌を歌った後、
そのままソーラーの額に寝っころがりながら
ソーラーの額をぴちぴちたたきだす。
ニーモ 「おっもしろ~い。」
元気な妖精からは絶え間なく光があふれだし
ソーラーにもその光は直接ふりそそいでいた。
ソーラー「つまり、今のプログラムでは
int a;
a=1.05;
このように
実数値1.05を整数型であるint型の変数aに格納するから
小数点以下の数値0.05は
切り捨てられ
変数aには1しか格納されないんだよね。
だから
今の目的のプログラムの実行結果
あなたの預金額はただいま10500円です。
が表示されないプログラム
👇
#include <stdio.h>
int main(void)
{
int a;
a=1.05;
printf("あなたの預金額はただいま%d円です。\n",10000*a);
return 0;
}
プログラムの実行結果(EAZY IDECの場合)
プログラムの実行結果(Visual Studioの場合)
あなたの預金額はただいま10000円です。
👆
を変更して
あなたの預金額はただいま10500円です。
と表示させるには
int a;
a=1.05;
によって
変数aに格納される数値が1.05から1に変更されるのを
ふせぐため
次のプログラムのように
#include <stdio.h>
int main(void)
{
float a;/*ここがかわりました。*/
a=1.05;
printf("あなたの預金額はただいま%d円です。\n",10000*a);
return 0;
}
と記述されなくちゃいけないんだね。」
(ほんとかな~~?(*´▽`*))
ソーラー「それでは😊
コンパイルっ」
プログラムの実行結果(EAZY IDECの場合)
あなたの預金額はただいま-262144000円です。
プログラムの実行結果(Visual Studio2018の場合)
C4305 '=': 'double' から 'float' へ切り詰めます。 Project6 c:\users\solarplexuss\source\repos\project6\project6\source.cpp 6
警告 C4477 'printf' : 書式文字列 '%d' には、型 'int' の引数が必要ですが、可変個引数 1 は型 'double' です Project6 c:\users\solarplexuss\source\repos\project6\project6\source.cpp 8
と表示されますが
プログラムの実行結果
あなたの預金額はただいま0円です。
が
コマンドプロンプト画面に表示されます
プログラムの実行結果(Visual Studio2019の場合)
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
警告 C6273 整数でない値が _Param_(2) として渡されました。'printf' への呼び出しには整数が必要です。実際の型: 'float': ポインター値を渡す場合は、%p を使用してください。 Project2 C:\Users\solar\source\repos\Project2\Project2\program1.cpp 8
警告 C26451 演算のオーバーフロー: 4 バイトの値に演算子 '*' を使用し、結果を 8 バイトの値にキャストしています。オーバーフローを避けるため、演算子 '*' を呼び出す前に値を幅の広い型にキャストしてください (io.2)。 Project2 C:\Users\solar\source\repos\Project2\Project2\program1.cpp 8
警告 C4305 '=': 'double' から 'float' へ切り詰めます。 Project2 C:\Users\solar\source\repos\Project2\Project2\program1.cpp 6
警告 C4477 'printf' : 書式文字列 '%d' には、型 'int' の引数が必要ですが、可変個引数 1 は型 'double' です Project2 C:\Users\solar\source\repos\Project2\Project2\program1.cpp 8
と表示されますが
プログラムの実行結果
あなたの預金額はただいま0円です。
が
コマンドプロンプト画面に表示されます
ソーラー「ははは
intをfloatに変えてプログラムを記述すると
うまくいくは・・・
ず・・・???😝
プログラムの実行結果(EAZY IDECの場合)
あなたの預金額はただいま-262144000円です。
!!!
な、なんで・・・?
どしぇえええええええ~~~
ついでに
プログラムの実行結果(Visual Studioの場合)
あなたの預金額はただいま0円です。
だってぇ~?」
🍋🍋🍋
なぜ このようなことが起きるかというと
printf("あなたの預金額はただいま%d円です。\n",10000*a);
に秘密があります。
今のプログラムの場合
a=1.05が10000*aに代入されるので
10000*a=10500となり
整数値を出力するのに用いられる%d出力変換指定子でよいのではないかとおもわれるとおもいます。
わたしも そうおもいました。
ですが タイトル名にもありますように
🍅実数値が1つでも計算式中に含まれている場合は
計算結果が整数値になっても
%d出力変換指定子でなく%f出力変換指定子を使用する🍅
という仕様になっています
なぜ このようなことが起きるのかというと
それは コンピュータの数値計算方法の仕組みにあります。
コンピュータは
整数型なら整数型
実数の型なら実数の型の形式でメモリに格納されている数値同士でしか計算を行うことはできません。
同じ整数の型の形式でメモリに格納されている数値同士の計算
5×5
5+5なら
そのまま計算を実行できますが
異なる型の形式でメモリに格納されている数値同士の計算
5×8.28888や
1.23456+10などは
そのままでは計算できないのです
詳しく説明すると
printf("あなたの預金額はただいま%d円です。\n",10000*a);
において
10000は整数なので整数の型(int)の形式でメモリに格納されます。
(つまり
コンピュータのメモリ内では
10000はint型の形式で格納されています。
このことは
ビット・バイトの説明のときに詳しく解説されます)
そして
10000*aの変数aがfloat型の変数の場合
変数a(に格納されている数値データ)は実数の型の形式でメモリに格納されているので
このままでは
整数値の型の形式でメモリに格納されている10000×実数の型の形式でメモリに格納されている変数a(に格納されている数値データ)
となってしまい計算できません。
そこでコンピュータは
整数値10000を実数10000.000000・・・に変換
そして 実数の型(double)の形式でメモリに格納しなおします
そのように整数値10000を実数に変換して
同じ実数型同士である
実数の型の形式でメモリに格納された実数値×実数の型の形式でメモリに格納された実数値の計算にもっていきます。
つまり
実数の型の形式でメモリに格納されている10000×実数の型の形式でメモリに格納されている変数a(に格納されている数値データ)
に変換して計算をおこなうというわけです。
このように
🍓実数の型の形式でメモリに格納されている実数値と🍓
🍓整数の型の形式でメモリに格納されている整数値の計算では🍓
🍎整数の型の形式でメモリに格納されている整数値は🍎
🍎実数の型の形式でメモリに格納し直されることになります つまり実数値に変換されます。🍎
そのようにして
実数の型の形式でメモリに格納されている実数値同士の計算に変換されてから
数値計算がをおこなわれるというわけです。
つまり
計算式中に1つでも実数があれば
その計算式の中の他の整数値はすべて実数値に変換されます。
そして
その計算結果も
実数の型(double)の形式でメモリに格納されます。
よって10000*aは実数となるわけです
ですので
10000*a=実数(🌞実数というところがポイントです)
をprintf出力表示するには%d出力変換指定子でなく
%f出力変換指定子が必要になってくるというわけです。
よって
今のプログラム
👇
#include <stdio.h>
int main(void)
{
float a;
a=1.05;
printf("あなたの預金額はただいま%d円です。\n",10000*a);
return 0;
}
プログラムの実行結果(EAZY IDECの場合)
あなたの預金額はただいま-262144000円です。
プログラムの実行結果(Visual Studioの場合)
あなたの預金額はただいま0円です。
👆
は整数値を出力する%d出力変換指定子を
実数値を出力する%f出力変換指定子にかえて
👇
#include <stdio.h>
int main(void)
{
float a;
a=1.05;
printf("あなたの預金額はただいま%f円です。\n",10000*a);
/*🌞%dが%fにかわりました。🌞*/
return 0;
}
と記述するのがただしいというわけです😊
そうすると
プログラムの実行結果(EAZY IDECの場合)
あなたの預金額はただいま10499.999523円です。
がprintf出力表示されます。
プログラムの実行結果(Visual Studioの場合)
C4305 '=': 'double' から 'float' へ切り詰めます。 Project6 c:\users\solarplexuss\source\repos\project6\project6\source.cpp 6
が表示されますが
プログラムを実行すると
あなたの預金額は10500.000000円です。
がprintf出力表示されます。
めでたしめでたし😊
🍋🍋🍋
って めでたくないって?
ソーラー「a=1.05が10000*aに代入されるのであれば
プログラムの実行結果(EAZY IDECの場合)は
10000*a=10500.000000となるはず
それが10499.999523・・・
になるって・・・???
統合開発環境Visual Studioでは
正しく
あなたの預金額は10500.000000円です。
が表示されてるのに・・・?」
🌞 🌞 🌞
ここで
統合開発環境EAZY IDECと
統合開発環境Visual Studioの違いが
はっきりでてきましたね。
なぜ統合開発環境EAZY IDECでは
プログラムの実行結果
あなたの預金額は10499.999523円です。
がprintf出力表示され
統合開発環境Visual Studioでは
プログラムの実行結果(Visual Studioの場合)
あなたの預金額は10500.000000円です。
と正しくprintf出力表示されるのか?
統合開発環境Visual Studioは最新の統合開発環境なので
正確に
あなたの預金額は10500.000000円です。
が表示されていますが
古いタイプの統合開発環境EAZY IDECでは
あなたの預金額は10499.999523円です。
となぜか微妙な数値が表示されています。
おもしろいですね。
実は
古いタイプの統合開発環境EAZY IDECは
正しく計算結果を表示しています。
この違いがなぜでてくるのかは
コンピュータの数値計算の仕組みを理解すれば
わかるようになります。
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます