留年戦記

留年と工学と人間関係と毎日戦っている人のブログです. 今年は留年回避済み.プロマネのお勉強中.留学試みたりTOEICの得点向上を試みたり.普通に学校の勉強を頑張ったり工学(プログラミングも回路も)について学んでみたり.時々レーザーカッターのパラメータを記事にしてます.

【C言語】型による表現範囲・精度のお話

以前,Takuya.Bさんからfloatとdoubleの記事かくならlong floatとかも書いて!と言われてしまったので,やっとこさ重い腰を上げて(嘘です.嘘です.この前提の話をひたすら書いてたので遅くなりました)精度について書こうと思います.

 

ちなみに,データ型についてはTakuya.Bさんが記事を書かれるそうなので是非そちらもどうぞ~!(現在確認したらまだ書かれていないようでしたが,C言語書き方について連載されているのでC言語の基本を教えて!という方はおすすめですよ~!分かりやすいのです!)

 

というわけで本題です.

1,データ型(ちょろっと)

そこまできっちりと話はしません.(ちゃんと話さないなんて珍しいでしょ?)

というのも,いつも,いつも本題に入る前に…と解説してたら本題が何週間たっても出てこないなんてざらになってきたからです(笑)

というわけで簡単な解説になります.

データ型とは所謂,「メモリを使用するときにどんな風に記述されてるの?どれくらいメモリ確保するの?どんな内容が記述されてるの?」と知るためのものです.

初心者殺し的発言はこれまでにして,

データ型というのは,ある変数に対してこれがどんな数値なの?と表す箱みたいなイメージです.「整数だよ!」と宣言された箱には整数の入った変数しか入れられません.

 

データ型には整数型や浮動点小数型などがあります.

これらは,どんな内容の数値かを示すものです.

整数であったり,小数であったり,はたまた文字であったり…と.

で,なんでさっき所謂~~のあとにあのような内容を言ったのかというと,メモリに記述されるときに記述方法がデータ型によって違うのです.

で,データ型によって異なるために表現可能な範囲が異なるのです.

このおかげで私たちは小数の計算や整数の計算をPC上で行えるのです.

 

データ型にはこんなに種類があります.

(ほかの言語にはもっとあったりなかったり)

f:id:aconote:20161118175019p:plain

 

 

2,整数型

最初はやっぱりこれです.

intやcharがありますね(char型はちょっと特殊です)

ほかのについてはintやcharの派生なのでよいとして,

char型は特殊です.

通常整数型としては使用しません.そのため1byte=8bitなのです.

8bitといえば,思いつく人いませんか?

表現範囲から一つ思いつかれる方はいらっしゃいますよね.

そう,「文字」です.「文字列」じゃないですよ.単体「文字」です.

ASCIIコードというものをchar型は表現します.

そしてもう一つよく使われるのはポインタです.「*」という文字を見たことあるでしょか?アドレスは8bitなのでchar型を使用することが多いのです.

 

そしてshortなどは今はあんまり使われているのを見ていませんね….

飛ばしてint型はよく使用されます.

この型に関してはマシン依存で精度が異なります.

(なんだか最近のPCはメモリが大量なので基本的にlong intと変わらないとか?

long intはもともとint型二つ並べましょうね~というものでした)

 

そしてunsigned ****というのは自然数のみですよ~という意味です.

なぜこんなものがあるのかというと,こうすると表現範囲が自然数型に偏り正の範囲が広がるからです.

負の数使わないのにっ!ってあるじゃないですか.あれです.

 

この整数型についてはそれぞれのbitを素直に使います.

電球でいうところの点灯しているかしていないかで使用します.

ので表現範囲が2の乗数となるのです.(ただし,0が含まれるため,上は1つ小さくなります)

これらは10進数と1対1関係なので下の記事のような木っ端みじんにまではならないはずです…(たぶん)

 

aconote.hatenablog.com

 

3,浮動点小数

表で小数と書いたところです.

これについてはトリッキーなので問題がよく発生します.

(ほとんどコレが問題でエラーが生じます)

 

今はfloatとdoubleだとdoubleのが処理も早いしうんぬんかんぬんと聞きますね.

実際どうなんでしょう(検証してないです)

 

この二つについては下のようにbitが分けられて使用されています.

()がbit数.

floatの場合

符号(1) | 指数部(8) | 仮数部(23)

doubleの場合

符号(1) | 指数部(11) | 仮数部(52)

です.

 この仮数部が何をしているのかというと1の位が1になるように入ってきた数字を2進数で表します.

符号については1か0で正負の判定になります.

指数部は入ってきた数字仮数部で正規化(1の位に1がくるようにすること)をしたあと,何をかけたらもとに戻るかの数字)を2進数にしたあとそれに127というオフセットを加えます.

(これをなんでするのかをちゃんと理解できなかったのでなんでするのか理解できたころに解説しますね)

これを指数部にしているのです.

これが浮動点小数の正体です.

聞いてみてやっぱり誤差が生じるだろ,この表現方法!と思われた方いらっしゃいますよね(;´д`)トホホ

でも,これがおそらく一番表現できる範囲が広いのだろうと思われます(思ってるだけでそうじゃないかも)

でも,小数に対して誤差のないデータ型をCにも作ってほしいものですよね(C#には存在するので)

 

というわけでC言語の表現範囲と精度のお話でした~