作成日: 2023/01/12 更新日: 2023/03/25
初めに
- 私たちは、紙の上で計算(特に加減乗除)をするとき、値の大きさや小ささ(値の範囲)を意識することが、ほとんどありません。
- ところが、コンピュータで計算する時、ある決まった範囲の値である必要があります。
コンピュータが計算できる(保持できる)値の範囲
- コンピュータの値の最小単位を1ビットと呼びます。
1ビットは、0か1の値のいずれかになります。 - ビットを8つまとめたものを1バイトと呼びます。
整数
値の表記方法
- コンピュータの値を表記する時、16進法を用いるのが一般的です。
- 以下に、4ビットの値の場合の2進法、10進法、16進法の表記表を挙げます。
2進法 | 10進法 | 16進法 |
0000 | 0 | 0 |
0001 | 1 | 1 |
0010 | 2 | 2 |
0011 | 3 | 3 |
0100 | 4 | 4 |
0101 | 5 | 5 |
0110 | 6 | 6 |
0111 | 7 | 7 |
1000 | 8 | 8 |
1001 | 9 | 9 |
1010 | 10 | A |
1011 | 11 | B |
1100 | 12 | C |
1101 | 13 | D |
1110 | 14 | E |
1111 | 15 | F |
自然数
- 上表のように4ビットを16進法で1桁(0~F)で表記できますので、1バイト(8ビット)は16進法の2桁で表記できます。
- 例えば、”7B”の時、7x2の4乗+B(11)=112+11=123
- そして、自然数を1バイトで表現すると0(00)~255(FF)の範囲の値をとることができます。
- 尚、負の整数については整数の演算を参照してください。
実数
- コンピュータで実数を表記する時、実数表記のために用いられたサイズ(バイト数)中の決められたビットサイズを整数部と少数部に割り当てます。
- コンピュータで実数を表記する時、次の2通りの方法が用いられますが、一般的には浮動小数点法が使用されます。
- 固定小数点法:ある決まったビットサイズを整数部、少数部に割り当てます。
- 浮動小数点法:値は、(−1)s × c × bqで計算されます。
s>符号ビット
c>仮数部
b>基数(2,10,16が存在しますが、この値は数値ごとではなく、使っているMPU/CPUなどに依存します。ところが、依存する基数を調べることはなかなか難しいようです。)
q>指数部
IEEE 754-(2008)
- 浮動小数点の表記規格です(2008年に改訂されています)。
詳細は、IEEE 754を参照してください。 - 上述したように、浮動小数点の値は(−1)s × c × bqで計算されます。
そして、IEEE 754では、s,c,b,qの値や割り当てビット数が規格として定められています。- s>符号ビット(1ビット)
- c>仮数部(23,52,112ビット)
- q>指数部(8,11,15ビット)
- b>IEEE 754でこの値(基数)は2になっています。
インテル系MPUのレジスタ
- レジスタとは、MPU(CPU)が持つ高速演算用一時的記憶装置のことです。
- そして、レジスタは機能によって数種類に分類されます。
この記事では、演算用のレジスタをターゲットにします。 - データは、MPU(CPU)と直結しているメモリ(メインメモリ・実装メモリ)に保持されています。
ハードディスクやSSD、USBメモリはMPU(CPU)と直結していません。 - MPU(CPU)が演算を行うとき、レジスタxレジスタ・レジスタxメモリのいずれかで行います。
整数の演算
- インテル社製ペンティアムⅣ(2000年発売)の頃から、レジスタは64bitになりましたので、レジスタが実行できる整数演算の最大値は、64ビットとして考えます。
- レジスタの最大値は8バイト(64ビット)ですが、1バイト、2バイト、4バイトの値の演算は、64ビットレジスタの一部を使用して行われます。
- 負の値の演算を行う時、レジスタの最も左のビットをサインビットとして扱います。
実数の演算
- IEEE 754に準拠します。
高水準言語(高級言語)と低水準言語(低級言語)
- 高級言語は、人間に分かりやすい言語・構文で構成された言語で、C言語・C++・JAVAなどが属します。
- 低級言語は、コンピュータがわかりやすい言語・構文で構成された言語で、8086アセンブラなどが属します。
- 高級言語のほとんどは、専用のコンパイラというプログラムを機械(マシン)語に変換する機能を持っていますが、汎用的な変換を求められるために、効率の悪い変換(マシン語が多くなる)になります。
- 低級言語は、アセンブラという機能で、言語対機械(マシン)語をほとんど1対1で変換します。
高級言語(変数の型)
- 高級言語は、言語により構文は少し違いますが、変数(データ)の型を持っています。
- つまり、変数の型は言語の仕様によって決められます。
整数型
- 整数型は、以下のように厳密な値の範囲を持っています。
- unsigned short int(符号なし短整数型)2バイト:値>0~65,535
- signed short int(符号付き短整数型)2バイト:値>-32,768~32,767
- unsigned long int(符号なし長整数型)4バイト:値>0~4,294,967,295
- signed long int(符号付き長整数型)4バイト:値>-2,147,483,648~2,147,483,647
- unsigned long long int(符号なし長長整数型)8バイト:値>0~18,446,744,073,709,551,615
- signed long long int(符号付き長長整数型)8バイト:値>-9,223,372,036,854,775,808
~9,223,372,036,854,775,807
浮動小数点数型
- float(単精度浮動小数点型)4バイト:値>
- double(倍精度浮動小数点型)8バイト:値>
低級言語(変数の型)
- 変数の型はレジスタに依存します。
演算時の注意
演算エラー
- 演算の過程あるいは、結果を保持する時、エラーとなる代表的な例を以下に記述します。
- ゼロ除算:ゼロによる除算
- オーバーフロー:保持できる値を超過
有効桁数
- 紙上で演算する時、「小数点以下3桁を有効数字とする」などという制約を設けることがあります。
これは、「測定値がmmなのでm以下3桁しか測定していないのだから4桁目以降には意味がない」という場合などに相当します。 - この時、小数点以下4桁目以降によって3桁目の値を丸めることがよくあります(四捨五入など)。
- MPU(CPU)も浮動小数点演算のとき、丸めを行いますが、これは、小数点の位置を意識したものではなく、最終ビットの値の丸めを意味します。
- 小数点位置を意識した丸めは、ソフトウェアによって行う必要があります。
- さらに、指数部の値が大きくなっていくと、有効桁数を侵食し、意味のない数値になることがあります。
- 浮動小数点の値同士の乗算の結果は、指数部同士の足し算になります。
つまり、小数点の位置がどんどんゼロから離れていくことを意味します。 - 回避方法は、計算式をコンパクトにし、冗長的な演算を行わないことです。
- 浮動小数点の値同士の乗算の結果は、指数部同士の足し算になります。
正規化
- ある一群のデータが存在する時、「その中数(平均)をとり、各データから中数を減じて、一定の処理をして、処理後結果に中数を加算する」というテクニックが存在します。
- この事により、一般的に処理するデータの値が小さくなり、有効数字を維持しやすくなります。
値が小さいということは、指数部も小さくなるということです。 - 各データから中数を減じることを、正規化と呼びます。
- また、各データを0~1の範囲に加工することを正規化と呼ぶことがあります。
- 正規化の目的は、MPU(CPU)の演算による有効数字の桁落ちを防ぐことにあります。
最後に
- 何も考慮しないで、浮動小数点演算を行うと、予期せぬ演算結果が出ることがあります。
- それを回避するため、データの正規化を行ったり、演算回数を少なくする必要があります。
- また、MPU(CPU)のレジスタや丸めの影響で、同じプログラムでも違うコンピュータでは、異なる演算結果が出る可能性も極僅かですが、あります。