天国にいけるC言語入門 シーズン1 パソコン超初心者がゼロから東方風シューティングをつくる編 ver.0.4.15.789 RELIEF
☆☆☆JIS丸めとコンパイラ コンパイラプログラムにはJIS丸め近似ルールが採用されています
☆☆☆JIS丸めとコンパイラ コンパイラプログラムにはJIS丸め近似ルールが採用されています
☆☆☆ JIS丸めとコンパイラ ☆☆☆
☆☆☆コンパイラプログラムにはJIS丸め近似ルールが採用されています☆☆☆
マックス 「すばらしいご説明ですね。(^^) 御老人。
・・・よく・・・ わかっちゃったよよんんっ~
よもや C言語でこのようなお話が聞けるとは・・・
全くおもいませんでした。
脱線ばんざい\(^o^)/」
深々とおじぎするマックス。
その前をひらひらと天国蝶が飛んでいく。
老人 「いや。なあに。
たまたまレポートに書いてあるのを
知っとったんじゃよ。
それにしても天国蝶がよ~くとんどるのう・・・」
また別の天国蝶がひらひらと二人の前を飛んでいく。
マックス
「それにしても四捨五入法の一部のルールを変更して
JIS丸め近似ルールをつくるとは より精密な値を求めようとする
先人の努力に畏敬の念を感じざるをえません。」
老人 「そうじゃのう。よほどそこまでするほど細かい誤差を
取り除く必要があったのかもしれんのう。
もしかしたら原子や電子の重さの測定につかったのかもしれんのう。
さあ、どうかのう。」
マックス
「それは ありえそうな話です。
原子や電子の重さの判定ならデータを大量に何回も測定して
入手しなければならないだろうし
さらにその大量のデータを平均して
原子や電子の重さをもとめるなら
JIS丸め近似ルールは有効に働くかもしれません。」
意外な科学の世界の知識に触れるマックスだった。
老人 「ところで なぜ その茶色いレポート用紙に
JIS丸め近似ルールがでてくるのじゃ・・・?」
マックス 「おおっ そうだ
これはC言語に関してのレポートなはず。
なぜ・・・?
そうだ 続きをよんでみましょう。
え^^~と
コンパイラの近似方法・・・だって?
10進数数値の四捨五入のような感じで
コンピュータ内で2進数数値の近似がおこなわれるときがあります。
そして どのように近似がおこなわれるかを指示しているのが
🍅コンパイラ(プログラム)🍅
なのです。
コンピュータが自動的に近似をおこなっているわけではないのです
2進数数値を近似する際
0捨1入の方法がおこなわれます。
例
10101
の
右から1番目の位の数値1を0捨1入すると
1は10となります
ですので
10110
になります。
例
10100
の
右から1番目の位の数値0を0捨1入すると
0はそのまま0となります
ですので
10100
になります。
例
10101
の
右から二番目の位0を0捨1入すると
0以下の位はすべて切り捨てられます
ですので
10100
になります。
例
10111111000111
の
右から二番目の位を0捨1入すると
1が繰り上がり
10111111001000になります。
例
10111011
の
右から五番目の位を0捨1入すると
1が繰り上がり
11000000になります。
その際
0捨1入した位より下の位はすべて0になります
例
10000011
右から五番目の位を0捨1入すると
10000000となります
このときも
0捨1入した位以下の位の数値はすべて切り捨てられ0になります」
老人 「ここまでは10進数の四捨五入と同じ感じじゃのう。
さらに詳しい例がここにかいてあるわい↓」
さて
ここで
1000(10進数8)
1001(10進数9)
1010(10進数10)
1011(10進数11)
のような4つの2進数データがあるとします
これらの数値の合計値は
100110(10進数38)
となります
これらの元データの1の位(2の0乗の位👈ともいいます)を0捨1入
するとします
すると
1000(10進数8)
1010(10進数10)
1010(10進数10)
1100(10進数12)
となります
これらの数値の合計値は
101000(10進数40)
となります
全体の数値の足し合わせた合計値が
元のデータの合計値よりおおきくなりましたね
なぜ
これらの元データの1の位(2の0乗の位👈ともいいます)を0捨1入
すると
0捨1入に酔った得られたデータの合計値がおおきくなるのでしょうか?
そ・こ・の・あ・な・た・・・💖
どう思われますか?
マックス「ふはは~~ 簡単だな
そもそも
元のデータの値の1の位に
0捨1入が行われると
1の位が0なら0を切り捨て
1の位が1なら10と切り上げ
になるなら
得られるデータは
🌞絶対🌞
元のデータの値と同じ値になるか
元のデータの値より大きくなるのはあたりまえのことじゃないか😊
0を切り捨てても元の値と同じだし
1なら10と切り上げるのなら元の値よりおおきくなるからなあ
だから
元のデータの値の1の位の数値を
0捨1入して
得られるデータを足し合わせたものは
元のデータを足し合わせたものと同じか
元のデータを足し合わせたものよりおおきくなる
って??
あんまり
0捨1入を行うメリットがないんじゃないか😊
うぃぃ~」
そ・こ・の・あ・な・た・・・
センスあるぅ
そう0捨1入によって得られたデータの平均値はかならず元のデータの平均値より大きくなります
そこで・・・
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
以下キラキラのレポートより
10進数のJIS丸め近似ルールのように
2進数の0捨1入にも似たような特殊ルール=JIS丸め近似ルールがあり
1の位を0捨1入するとき
元のデータを
例10001 (1の位の数値を0捨1入したいとき)
例11111(1の位の数値を0捨1入したいとき)
とすると
そのときはひとつ上の10の位の数値(2の1乗の位とも言います)を見て、
その10の位の数値が
0なら1の位の1を切り捨て、
1なら1の位の1を切り上げとするというルールがあり
元のデータは
次のように切り捨てまたは切り上げされます。
例10001→10000
(例10001において
1の位の、ひとつ上の10の位は0なので
1の位の1は切り捨てられこの結果となりました。
👆ここが普通の0捨1入法と違うところです
普通の0捨1入法では
1の位の1は切り上げられ
10001→10010
となります)
例11111→100000(例11111において
1の位の、ひとつ上の10の位は1なので
1の位の1は繰上げられ10となるので
11111=
11110+1から
11110+10となり
この結果となりました)
ここでJIS丸め法をコンパイラが採用していないとすると
例10001 (1の位を0捨1入したいとき)
例11111(1の位を0捨1入したいとき)
は普通に0捨1入され
10001→10010
11111→100000
と近似されます
両方のデータとも元のデータの値よりもおおきくなりましたね
もう1つ例を見てみましょう。
数値を0捨1入をおこない近似を行う場合
JIS丸めが適用されるためには
近似をしたい位より1つ上の位は
0で
近似をしたい位より以下の位はすべて
0であることが必要となります
例えば
近似をしたい数値が
例101100(100の位を0捨1入したいとき)
例100100(100の位を0捨1入したいとき)
の場合
例101100
は
100の位の一つ上の1000の位(2の3乗の位)は
0でなく1なので
JIS丸めは行われず普通に
100の位の数値1が0捨1入され
101100→110000
となります
例100100の場合は
近似を行いたい100の位(2の2乗の位)より一つ上の位は
0で
近似を行いたい100の位(2の2乗の位)より下の
10の位(2の1乗の位)
1の位(2の0乗の位)
ともに
0なので
JIS丸めが適用され
100の位(2の2乗の位)の1は切り捨てられ
100100は100000
となります
JIS丸めがどのように適用されるかをみてきましたが
実際に
どのようにJIS丸めが有効なのか
1つの例をみていきますね。
これから
次の数値たちの
右から1番目の位の数値を
1.普通の0捨1入法
と
2.JIS丸めを取り入れた0捨1入法
2つのパターンを用いて
繰り上げ または切り捨てを行うことにより
近似をおこなってみます
1000000
1000001
1000010
1000011
1000100
1000101
1000110
1000111
👆
これらの数値ですね
簡略化のために
右から3番目の位までを以下のようにとりだしてみます。
000 (10進数0)
001 (10進数1)
010 (10進数2)
011 (10進数3)
100 (10進数4)
101 (10進数5)
110 (10進数6)
111 (10進数7)
これらの8つの数値をたしあわせたものは28となっています
平均値は28÷8=10進数3.5となります。
普通に1の位に0捨1入が行われると
000 (10進数0)
001 (10進数1)
010 (10進数2)
011 (10進数3)
100 (10進数4)
101 (10進数5)
110 (10進数6)
111 (10進数7)
は
000 (10進数0)
010 (10進数2)
010 (10進数2)
100 (10進数4)
100 (10進数4)
110 (10進数6)
110 (10進数6)
1000(10進数8)
となり
これらの8個の
数値をたしあわせたものは10進数32となります
平均値は
32÷8=4ですね。
元のデータの平均値は3.5でしたので
誤差は4-3.5=0.5になります。
次に
000 (10進数0)
001 (10進数1)
010 (10進数2)
011 (10進数3)
100 (10進数4)
101 (10進数5)
110 (10進数6)
111 (10進数7)
に
JIS丸めを適用して近似してみましょう。
この
0と1のみで表される2進数で
JIS丸め法が使われるには
まず
JIS丸めを行う1の位以下の位の数値はすべて0になっている必要があります。
ここではもちろん0捨1入する1の位以下の数値は存在しないので条件をみたしています
加えて
JIS丸めを行う1の位より1つ上の位は0になっている必要があります。
1の位の数値に
0捨1入とJIS丸めが合わせて行われると
000 (10進数0)
001 (10進数1)
010 (10進数2)
011 (10進数3)
100 (10進数4)
101 (10進数5)
110 (10進数6)
111 (10進数7)
は
000 (10進数0)
000 (10進数0)👈001の右から1番目の位の数値1の左の位には0
が格納されているので
普通の0捨1入法では1を切り上げる所をJIS丸め法により1を切り捨てました
010 (10進数2)
100 (10進数4)
100 (10進数4)
100 (10進数4)👈101の右から1番目の位の数値1の左の位には0
が格納されているので
普通の0捨1入法では1を切り上げる所をJIS丸め法により1を切り捨てました
110 (10進数6)
1000 (10進数8)
のように近似されます。
これらの8つの数値をたしあわせたものは28となっています
平均値は
10進数3.5
となります。
元のデータの平均値は3.5でしたので
元のデータとの差は0
JIS丸めを取り入れた0捨1入法が行われたデータの平均値と
元のデータの平均値
は一致しています
普通に
000 (10進数0)
001 (10進数1)
010 (10進数2)
011 (10進数3)
100 (10進数4)
101 (10進数5)
110 (10進数6)
111 (10進数7)
を
足し合わせた数は28
平均値 3.5
0捨1入した場合は
足し合わせた数は32
平均値 4
0捨1入とJIS丸めが合わせて行われた場合は
足し合わせた数は28
平均値 3.5
となり
0捨1入が行われた場合のほうは
元の値のデータの平均値との差は4-3.5=0.5
0捨1入とJIS丸めが合わせて行われた場合のほうは
元の値のデータの平均値との差は3.5-3.5=0
となり
0捨1入とJIS丸めが合わせて行われた場合は
元の値のデータの合計値28
元の値のデータの平均値3.5
そのものになっていることがわかります
0捨1入とJIS丸めを行って近似したほう0捨1入を行った場合より精度が高くなっています
そのため
JIS丸めが
2進数を近似するときの方法として採用されています
今のサンプルデータの場合では
普通の0捨1入法よりも
0捨1入法とJIS丸めをあわせてつかって
近似したときの方が誤差が0になっていますが
サンプルデータの状況によっては
JIS丸めで近似したときと
普通の0捨1入法で近似したときの
元のデータとの誤差が等しくなる場合があります。
必ずしも
JIS丸めで近似したときのほうが
普通の0捨1入法で近似したときよりも
元のデータとの差がすくなくなるとはかぎりません
サンプルデータが
次の3つの場合
000 10進数0
001 10進数1
010 10進数2
合計値は10進数3ですが
1の位で0捨1入が行われると
000 10進数0
010 10進数2
010 10進数2
となり合計値は4ですが
1の位でJIS丸めが行われると
000 10進数0
000 10進数0👈001の右から1番目の位の数値1の左の位には0が格納されているので普通の0捨1入法では1を切り上げる所を切り捨てました
010 10進数2
となりデータの合計値は2になります。
つまり 元のデータの合計値は3
普通の0捨1入法を行った場合のデータの合計値は4
JIS丸めを取り入れた0捨1入法を行った場合のデータの合計値は2
となり
元のデータの合計値
と
普通の0捨1入法を行った場合のデータの合計値
の差は1
元のデータの合計値
と
JIS丸めを取り入れた0捨1入法を行った場合のデータの合計値
の差は1
となり
ともに
元のデータの合計値との差が1となっています
実は
サンプルデータの状況によって
JIS丸めを取り入れた0捨1入法を行った方が
普通の0捨1入法を行った場合より
誤差が少ない場合もあれば
逆に
誤差が多い場合もあります
ですが
それは
サンプルデータ数が少ない場合
あるいは
サンプルデータの数値の分布に偏りがある場合での話であり
サンプルデータ数が多く
サンプルデータの数値の分布に偏りがない場合
JIS丸めを取り入れた0捨1入法で近似を行った場合のほうが
0捨1入法だけで近似を行った場合より
元のデーターの合計値と平均値の差が少なくなります
ですので
JIS丸めを取り入れた0捨1入法がコンパイラに採用されているのです。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
マックス「オオ、なぁるほどぉ😊」
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
以下きんきらりんのレポートより
コンピュータは大量の数値をあつかうため
近似による誤差がすこしでもなくなるよう
すこしでも計算結果が
真の値にちかづくよう
このような仕組み(JIS丸め)が
コンパイラに採用されています
この特殊ルールは IEEE 754という国際ルールの一部でもあり
コンパイラが2進数数値を近似するときに
このルールがつかわれているのです。
。。。。。。。。。。。。。。。。。。。。。。。。
マックス 「そのような理由で他の科学分野で
使われていた
JIS丸めルールがコンパイラにも
適用されていたとは・・・
奥深い・・・」
老人 「そうじゃのう。
JIS丸めとは全然関係ないんじゃが~~
ちょっとわしー
おもうんじゃが
例 11111
が(1の位が0捨1入されて)
100000(1の位のひとつ上の桁は1なのでJIS丸めはおこなわれません
1の位の1は10に繰上げられた。)
となった。
(11110+10がおこなわれています)
このようにコンパイラによって近似されたとするじゃろう。」
マックス 「はい。」
老人 「これは10進数に直されたなら
11111=31が
100000=32に
変化しているんじゃ。
あるいは
例11001(右から1番目の位を0捨1入する)
が
11000
(ひとつ上の桁は0JIS丸目が用いられ右から1番目の位の数値1は切り捨てられた。)
に近似されたときは10進数に直されたとき
11001=25が
11000=24に変化しておるということじゃ。
つまりじゃ
コンピュータの数値計算結果がコマンドプロンプト画面に
表示されるとき
なぜか
近似値が表示され
正しい答えがでてこない場合があるのも
このように元の2進数に近似が行われて数値が変化していては
バグでもなんでもなくて普通のことだとおもうんじゃ。」
マックス 「・・・! まさに、そのとおり。」
楽しげに蝶々は二人のそばを飛んでいく。
老人 「そしてじゃ
今の話と
ちょっと話は変わるが
コンパイラによって
数値計算の
結果が違うことがあるじゃろう。
ということは
コンパイラごとに
数値計算する方法が
違う
つまり
コンパイラが
数値計算のソースコードを
機械語に翻訳したものを
コンピュータが実行するんじゃが
コンパイラごとに
ソースコードの中の
数値計算に登場してくる数値の機械語への翻訳の仕方
が異なることがあるというわけじゃな。」
マックス「それで
コンパイラごとに
数値計算の計算結果が
異なることがあるってわけだ」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます