コンピュータに扱える数値には範囲があります。その4 ビルドエラーが出る数値計算のソースコードをデバッグしてみましょう。🌞

突然ですが、ここで練習問題です。


#include <stdio.h>

int main(void)

{

printf("%d\n",(10000 + 888100-555) * 100000/ 55);

return 0;

}


プログラムの実行結果(EAZY IDECの場合)

プログラムの実行結果(Visual Studioの場合)


-7796603



このプログラムの実行結果は


-7796603

が表示されていますが



計算上は


このプログラムが実行されると


1631900000


になるはずなのですが・・・


しかし


コマンドプロンプト画面に表示されている数値は


-7796603です。


このプログラムは


どこがまちがっているのでしょうか。・・・


マックス 「みなさん どこか目星がついたかな。」


てんC 「どの項目 、式 


いずれも、まちがっていないと


おもいますが・・・


ソーラー 「たぶん この


(10000 + 888100-555) * 100000/ 55があやしい。


ここに問題が・・・・どこに・・・」


てんC 「うん・・・・・・」


マックス


「あーーーーーーーーーーーーーーー」


ソーラー 「なにごとです。」


マックス 「エウリーカ、エウリーカ


われ、みつけたり。」


ソーラー、てんC 「えっっ・・・・・・・」


ぶーにゃん 「にゃんと?」


ソーラー 「この式のどこに問題が・・・」


てんC 「掛け算マークの書きまちがいでもありませんCー」


マックス 


「ふふふ・・・


printf関数内において


%d出力変換指定子は符号つき整数値を出力するのだった・・・」


にゃーん 「だった・・・・?」


ソーラー 「???・・・はい、そうですが・・・」


てんC 「・・・・・・・?」


マックス 「(10000 + 888100-555) * 100000/ 55)


ここに整数でない部分があるじゃんかー。


そこ そこ\(^o^)/


100000/55ですよー。」


ソーラー 「まっまさか・・・」


てんC  「それは・・・」



マックスさんは


(10000 + 888100-555) * 100000/ 55)の計算において


%d出力変換指定子は符号つき整数値しか取り扱えないのに


100000/55の計算結果が小数点以下の部分をふくむので


バグが生じるのではないかと推測しています



ぶーにゃん「でも 


プログラムにおいて整数値どうしの割り算の場合 


割り算の結果が実数値(小数点以下の項が含まれる数値)の場合


割り算の結果は


小数点以下が切り取られ


整数値になるんじゃなかったかにゃ?」


マックス 「ふふ 確かにそうだ。


ぶーにゃんよ。


だが100000/55は電卓で1818.18181818181818・・・


つまり無限小数。


整数値同士の割り算の結果の数値が


無限小数でもコンピューターは


小数点以下を切り取りきることができるかな?


無限に小数点以下が続く数値を計算しきれるかな?


無限に小数点以下が続く数値を切り取りきれるかな?っ


これがバグの原因だー


つまり このバグが-7796603をよびおこしているのだ!」


(嘘です)


ソーラー 「たっ確かに・・・これはあやしいっ!」


てんC 「おおっ なんという・・」


ぶーにゃん 「にやお!?」


キャラットを手からとりおとす猫。


マックス 「即 


100000/55


この部分だけをprintf出力表示だ。


もし


100000/55が原因で-7796603をおこしているなら


printf出力表示したとき1818という値はでてこないはず。


🍊🍊🍊

マックスの語った👆の部分の解説をおこなってみます。


100000/55は電卓で1818.18181818181818・・・


プログラムを使った計算では


整数値同士の割り算は


例えば

5/2ならば


5/2=2.5

の小数点以下が切り取られ


プログラムの実行結果は


2となります



しかし100000/55は1818.18181818181818・・・


と長すぎるなので


コンピュータは計算しきれず


よって


小数点以下を切り取りきることができない可能性があり 


1818



コマンドプロンプト画面にprintf出力表示されない


可能性があるとマックスは言っています。


                  solarplexussより

🍊🍊🍊


ソーラー

てんC

「ラジャー。」


「ラジャーです。」


マックス「100000/ 55をprintf出力表示だ。」


#include <stdio.h>


int main(void)

{

printf("%d\n",100000/ 55);


return 0;

}


マックス 「コンパイル!ッ」


プログラムの実行結果(EAZY IDECの場合)

プログラムの実行結果(Visual Studio2018の場合)


1818

続行するには何かキーを押してください_


プログラムの実行結果(Visual Studio2019の場合)


1818


C:\Users\solar\source\repos\Project2\Debug\Project2.exe (プロセス 7688) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...






マックス「しぇ~


あれっ


無限小数もただしくprintf出力表示され


1818.1818181818・・・・・の小数点以下の部分が切り取られ


1818となっている・・・・


いやいあy\(^^)/・」














  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る