☆☆☆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進数に近似が行われて数値が変化していては


バグでもなんでもなくて普通のことだとおもうんじゃ。」


マックス 「・・・! まさに、そのとおり。」


楽しげに蝶々は二人のそばを飛んでいく。



老人  「そしてじゃ


今の話と


ちょっと話は変わるが


コンパイラによって


数値計算の


結果が違うことがあるじゃろう。


ということは


コンパイラごとに


数値計算する方法が


違う


つまり


コンパイラが


数値計算のソースコードを


機械語に翻訳したものを


コンピュータが実行するんじゃが


コンパイラごとに


ソースコードの中の


数値計算に登場してくる数値の機械語への翻訳の仕方


が異なることがあるというわけじゃな。」


マックス「それで


コンパイラごとに


数値計算の計算結果が


異なることがあるってわけだ」















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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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