Float型の標準出力の有効数字のデフォルトはなぜ6桁なのか

---
<font color="blue">Float</font>型の標準出力の有効数字のデフォルトはなぜ<font color="green">6</font>桁なのか
---

**風船ガム**

イチゴ味の風船ガムを食べてました。

くちゃくちゃ味わい、ふくらます。
口に広がる甘酢っぱさ。
フルーティーが鼻をつつく。

何回かそれを繰り返していると　ふと
どれくらい大きくなるのだろうと
思いました。

おもいっきり息を吐き　
風船ガムをふくらませました。

ドンドン大きくなるガム。

破けることなく大きくなり
ついに私は空を飛びました。

ああ、でも残念なことに
私はずっと上を向いたまま。

下に広がる素敵な景色は見れません。

「私はどこまで浮かびつづけるのでしょうか」

浮かびながら空に聞くのでした。


**目次**
[1. そもそもFloat型って何？](#1-そもそもfloat型って何)
[2. Float型の標準出力の例](#2-float型の標準出力の例)
[3. なぜデフォルトは6桁なのか](#3-なぜデフォルトは6桁なのか)
[4. おわりに](#4-おわりに)



# 1. そもそもFloat型って何？

<font color="low blue">**Float型とは**</font>

　float 型は、コンピュータプログラミングにおいて、数値を表現するために使用されるデータ型の一つです。

 float 型の名前の由来は、その数値表現が「浮動小数点」(floating-point) 形式に基づいていることから来ています。この用語は、数値の小数点が「浮いている」（つまり、位置が固定されていない）ことを意味します。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493200/52451606-ca72-7ce5-0c13-2713cefbf01e.png)

<font color="low blue">**浮動小数点とは**</font>

　浮動小数点数とは、数値を符号部、指数部、および仮数部（または分数部）の3つの要素で表現し、これによって非常に大きい数値や非常に小さい数値を効率的に表現することができます。

　IEEE 754のbinary32（単精度浮動小数点数）形式において、数値は以下のように表されます。

 ```php
数値 = (-1)^符号部 * 1.仮数部 * 2^(指数部 - バイアス)
 ```
<br>

<font color="low blue">**仮数部、指数部、符号部**</font>

　float 型は、32ビットのメモリを使用し、そのビットは符号部、指数部、仮数部に分けられています。

　そこで、各部分の役割とビット数の割り当て、およびその理由について説明し、テーブル形式で整理してみます。
<br>

<font color="orange">**符号部**</font>
ビット数: 1ビット

説明: 数値の符号を表します。0は正、1は負を意味します。

理由: 符号部は数値が正か負かを示す必要があるため、1ビットあれば十分です（2状態、つまり正か負を表すことができます）。

<br>

<font color="orange">**指数部**</font>
ビット数: 8ビット

説明: 数値のスケール（大きさ）を決定します。指数部は、バイアス表記を使用して表され、実際の指数値に特定の数（127）を加えた値が格納されます。

　バイアス表記は、浮動小数点数の指数を表現するための工夫された方法です。バイアス表記は、指数が正の数値も負の数値も取り得ることを考慮し、すべての指数値を非負の整数としてエンコードするために使用されます。

　バイアス表記は奥が深すぎるのでまたの機会に。

理由: 8ビットを使用することで、十分な大きさと精度の範囲を提供し、非常に小さい数値から非常に大きな数値まで表現できます。

<br>

<font color="orange">**仮数部**</font>
ビット数: 23ビット

説明: 数値の実際のデータ（数字）を保持します。これは、数値の有効数字を表し、1.xxxxの形式の数値で、先頭の1は通常省略されます（暗黙のビット）。

理由: 仮数部は数値の精度を決定します。23ビットは、数値の精度と表現できる範囲のバランスを考慮して選ばれました。32 - 1 - 8 = 23

<br>

<font color="orange">**テーブル**</font>

|部分 |ビット数| 説明 |理由|
|-----|--------|----|-----|
|符号部 |1ビット| 数値の符号（正か負）を表す。 |正負2状態を表現するのに1ビットあれば十分。|
|指数部 |8ビット| 数値のスケール（大きさ）を表す。 |広範囲の数値を表現するために、十分な数のビットが割り当てられている。|
|仮数部 |23ビット| 数値の有効数字を表す。1.xxxx形式で、先頭の1は暗黙のビットとして省略される。 |数値の精度を決定し、適切なバランスを提供するために選ばれたビット数。|

# 2. Float型の標準出力の例

　では次に具体的な出力結果を複数の言語のコードで見て頂きます。

<font color="low blue">**C言語の場合**</font>
```php
#include <stdio.h>

int main() {
    float number = 0.1234567;
    printf("%f\n", number);
    return 0;
}
```
出力:
```php
0.123457
```

<font color="low blue">**C++の場合**</font>
```php
#include <iostream>
#include <iomanip>

int main() {
    float number = 0.1234567;
    std::cout << number << std::endl;
    return 0;
}
```
出力:
```php
0.123457
```

<font color="low blue">**Javaの場合**</font>
```php
public class Main {
    public static void main(String[] args) {
        float number = 0.1234567f;
        System.out.printf("%f%n", number);
    }
}
```
出力:
```php
0.123457
```

<font color="low blue">**Go言語の場合**</font>
```php
package main

import (
    "fmt"
)

func main() {
    var number float32 = 0.1234567
    fmt.Printf("%f\n", number)
}
```
出力:
```php
0.123457
```

# 3. なぜデフォルトは6桁なのか

　見て頂いてわかる通り、デフォルトだと、有効数字6桁で、7桁目は四捨五入されています。

 これは先程の仮数部が関係しています。

 　float 型は、仮数部に23ビットを使用し、加えて暗黙のビット（通常は1とされる）があるため、実質的には24ビットの精度を持っています。

　10進数の桁数は、2進数のビット数に対数を使って変換することができます。
 
 　具体的には、log10(2)（約0.3010）を使って変換します。
  
  　24ビットで表せる桁数を計算すると、以下のようになります：

```php
24ビット * log10(2)
-> 24 * 0.3010 = 7.224
```
 
  この計算により、float型が理論的には約7桁の精度を持つことを示しています。
  
　しかし、実際の計算で丸め誤差が生じるため、安全な有効桁数としては通常6桁が使用されます。

 2進数で表現される浮動小数点数は、特に10進数で表される数値を正確に表現できない場合があります（例えば、0.1や0.2など）。
 
　このような数値は2進数で近似値に丸められますが、その結果として微小な誤差が発生します。
 
　この誤差は、計算の過程で蓄積される可能性があります。

　なのでデフォルトでは主に、6桁の有効数字が使われているのです。
 

# 4. おわりに

　floatの記事を書くにあたり、IPv4が32ビットだったり、アスキーコードの幅が8ビットだったり、数字と実用性の美しい関係に思いをはせることができ、楽しかったです。

　浮いた気持ちを落ち着かせながら&hellip;&hellip;。