◎第7回 数値データの扱い

データ型とデータの表現

下へ一覧へ

〇テキスト
4章(4.1)

データ型: 変数や定数(データ)の種類. そのデータが使用できる数の大きさを表す.
  宣言: すべての変数は使用する前にその種類を宣言しなければならない.

下へ上へ

〇基本である数とその表現
10進数: 人間の理解できる数値そのもの
        0〜9
        3452(10進)=3×10の3乗 + 4×10の2乗 + 5×10の1乗 + 2×10の0乗
 2進数: ディジタル計算機内部で使う
        0または1
        1100(2進)=1×2の3乗 + 1×2の2乗 + 0×2の1乗 + 0×2の0乗
               =1×8 + 1×4 + 0×2 + 0×1 = 12(10進)
 8進数: 2進数の 3桁毎に区切って使う
        0〜7
16進数: 2進数の 4桁毎に区切って使う
        0〜9とa〜f

n 進数の n は 基数(radix)とよぶ。
( 基数の変換方法 )

下へ上へ

〇データ型とサイズ
 ・整数と実数(浮動小数点数)
    符号付き整数…正負の数が表現できる整数(負数の表し方)
    符号無し整数…正の数だけが表現できる整数
    浮動小数点数(実数)…正負の数と小数点以下の数や、より大きな数を表現できる実数
 ・C 言語における基本的データ型
    char   1バイト、1文字を保持…文字を表すのに用いる
    int    整数
    float  単精度浮動小数点数
    double 倍精度浮動小数点数
    さらに長さの指定 short(int)…16ビット符号付き整数
                      long(int)…32ビット符号付き整数
           int型…マシンに依存
                  ここでは単にint と書くとlong int
                  パソコンで単にint と書くとshort int

 ・ビット長…表現できる数の多さを決定する
          2ビットなら、「00,01,10,11」の4種類の数

 ・C言語で扱える数値のビット長
     8ビット幅・・・256(28)種類の数値が表せる
    16ビット幅・・・65,536(216)種類の数値
    32ビット幅・・・4,294,967,296(232)種類の数値
    64ビット幅・・・264種類の数値
数値の型数値の範囲数値の型数値の範囲
char-128 〜 +127unsigned char0 〜 255
short-32768 〜 +32767unsigned short0 〜 65535
long-2147483648 〜+2147483647unsigned long0 〜 4294967295
float/doubleおよそ10-79 〜 1075各データ型の表現できる範囲

下へ上へ

○実数の表現
  ・小数と分数
      10進数の小数    0.987 = 9×10-1 + 8×10-2 + 7×10-3
      2進数の小数      0.101 = 1×2-1 + 0×2-2 + 1×2-3 
      1/3は10進数では循環小数となる。0.33333333.....
      1/5は2進数では循環小数となる。 0.00110011.....
  ・計算機内部の表現
      浮動小数点数(実数)Aは
        A = a × b n          a:仮数部、b:基数(2 or 16)、n:指数部
      と表される。テキストでは正規化された表現(|a|<1)で定義される
      仮数部aのビット数が多いほど誤差が小さい(精度がよい)
      指数部nのビット数が多いほど表現範囲が広い
        10進数の場合   A = s×a.******(m桁)×10n    s=1 or -1(符号),a≠0
       2進数の場合    A = s×a.******(m桁)×2n    s=1 or -1(符号), a≠0すなわち a=1
                       常にa=1なので省略可能「暗黙の1」
          2進数小数の例
                0.0000010010111  有効桁数8ビット(初めての1から数える)
                1.0010111×2-6    仮数部7ビット

  ・精度と誤差
        実数型で表現された数値‥真の値に対する近似値
        計算機による計算が有限桁で行われることからくる誤差の例
          *いくつかの数を加算する場合の四捨五入誤差の累積
          *演算の順序を変えると結果が違う(結合則が成り立たない)
          *大きな数から大きな数を引くと有効数字が減り、相対精度が悪くなる(桁おち)
          *10進数の数を2進数に直して計算するときの変換誤差
              テキストの例
              (0.1)10 = (0.000110011001100110011001100.....)2
              (0.11001100110011001100110)2 × 2-3      0.75×2-26の誤差
               0.1を10回加えても1にはならない

下へ上へ

○定数と変数
  ・定数:プログラムの実行中を通して値を変えられない
  ・変数:主記憶装置(メモリ)内に確保したデータの記憶領域
          記憶装置内の位置をアドレスと呼ぶ。英字で名前をつけて取り扱う。
      宣言・・・変数の名前、型の対応付けをし記憶場所を確保する。
      例      int i;
              double x;

○型変換
  ・自動変換1・・代入するときには、自動的に型が変換される。
  ・自動変換2・・型の違う値どうしの演算は、一般には精度の高い方に変換してから行われる。
                  ただしCでは、float同士でもdoubleに変換される
  ・強制型変換・・強制的に型を変換するには、Cでは型キャストを用いる

下へ上へ

○演習7
7.1 自分の学籍番号を 2 進数, 8進数, 16 進数でそれぞれ表せ。
    それは、short int で表現できるか?

7.2 以下の3つのプログラムは正しく動作しない。
    そのままコピーしてコンパイル、実行し、結果を確認せよ。
    次にそれぞれ指示に従ってプログラムを修正して実行し、
    正しい結果が得られることを確認せよ。またその理由を説明せよ。

    (a) degreeをradianに変換してsin(x)を求めるプログラム sin7s.c
        の180を180.0に修正せよ。<理由>

    (b) 整数の表現範囲を確認するプログラムover.c
        のshort int をintに直せ。<理由>

    (c) 次の数値積分プログラムを、a=0 , b=1 , h=0.1で実行すると、
        停止しない。 integral7.c
       (from ? に対して 0 と入力し、to に対して 1、step に対して 
        0.1 と入力する。強制的に終了させるには ctrl-C をおす )
        ループ繰り返し条件(x!=b)を (x<=b)に直して実行せよ。<理由>

7.3 2次方程式の解の公式で -b と sqrt( b*b -4*a*c ) の絶対値が近い場合、
    二つの解の一方で、近い二つの値を引き算して精度が悪くなることが起きる。
    これを改善するには、まず絶対値の大きな解を求め、次に「解と係数の関係
     x1*x2=c/a」 を用いて他方の解を求めるとよい。
    両方法を比較して解を求めるプログラムが quad7a.c である。( PAD )
    コンパイル・実行して a=1 b=2 c=1e-6 の場合について確かめよ。
    (1e-6 は 1×10 の-6乗を意味する)
    このプログラムでは、それぞれの解のあと誤差を()内に表示する。
    ( 誤差は、 その解を方程式 ax2 + bx + c = 0 に代入し、左辺から右辺を引いた値 )

下へ上へ


一覧へ上へ

○レポート課題7  (解答) 

7.1 10進数(学籍番号の下3桁)+98 の逆数を2進数の小数で表せ。
    (有効桁数  2進数8ビット)
    また、仮数部 7 ビットの2進数浮動小数点表示で表せ。
    (指数部は10進数でよい)
    ヒント: 目的の数を2進数で表し 1÷(その数)を2進数で計算すればよい。
           この場合は小数点以下必要な桁まで計算する。

7.2 摂氏-華氏温度対応表を印字するプログラムtemp.c は正しい結果が
    得られない。2個所だけ修正し、0<=F<=200の範囲で表示せよ。
    修正したプログラムと実行結果のスクリプトを提出。

7.3 演習のプログラムを参考にして、xの平方根(0<=x<1)を
    0.1間隔で表示するプログラムを作成せよ。
    プログラムと実行結果のスクリプトを提出する。
    ヒント: printf("%g の平方根は %g\n", x, sqrt(x));

一覧へ