浮点型底层

1. 浮点型

浮点数,计算机中小数的表示方式,如:3.14

Go语言中提供了两种浮点型:

  • float32,用32位(4个字节)来存储浮点型。
  • float64,用64位(8个字节)来存储浮点型。
package main

import "fmt"

func main() {
    var v1 float32
    v1 = 3.14
    v2 := 99.9
    v3 := float64(v1) + v2
    fmt.Println(v1, v2, v3)
}

1.1. 非精确

float类型,计算机中小数的非精确的表示方式,如:3.14

package main

import "fmt"

func main() {
    var v1 float32
    v1 = 3.14
    v2 := 99.9
    v3 := float64(v1) + v2
    fmt.Println(v1, v2, v3)

    v4 := 0.1
    v5 := 0.2
    result := v4 + v5
    fmt.Println(result)

    v6 := 0.3
    v7 := 0.2
    data := v6 + v7
    fmt.Println(data)
}
3.14 99.9 103.04000010490418
0.30000000000000004
0.5

1.2. float底层存储原理

var price float32 = 0.29

第一步:浮点型转换为二进制

  • 整数部分,直接转换为二进制(10进制转换为2进制),即:100111
  • 小数部分,让小数部分乘以2,结果小于1则将结果继续乘以2,结果大于1则讲结果-1继续乘以2,结果等于1则结束。

    0.29 * 2 = 0.58       // 小于1,则继续乘
    0.58 * 2 = 1.16          // 大于1,则减1继续乘
    0.16 * 2 = 0.32          // 小于1,则继续乘
    0.32 * 2 = 0.64       // 小于1,则继续乘
    0.64 * 2 = 1.28       // 大于1,则减1继续乘
    0.28 * 2 = 0.56       // 小于1,则继续乘
    0.56 * 2 = 1.12       // 大于1,则减1继续乘
    0.12 * 2 = 0.24       // 小于1,则继续乘    
    0.24 * 2 = 0.48       // 小于1,则继续乘
    0.48 * 2 = 0.96       // 小于1,则继续乘
    0.96 * 2 = 1.92       // 大于1,则减1继续乘
    0.92 * 2 = 1.84       // 大于1,则减1继续乘
    0.84 * 2 = 1.68       // 大于1,则减1继续乘
    0.68 * 2 = 1.36       // 大于1,则减1继续乘
    0.36 * 2 = 0.72       // 小于1,则继续乘
    0.72 * 2 = 1.44       // 大于1,则减1继续乘
    0.44 * 2 = 0.88       // 小于1,则继续乘
    0.88 * 2 = 1.76       // 大于1,则减1继续乘
    0.76 * 2 = 1.52       // 大于1,则减1继续乘
    0.52 * 2 = 1.04       // 大于1,则减1继续乘
    0.04 * 2 = 0.08       // 小于1,则继续乘
    0.08 * 2 = 0.16       // 小于1,则继续乘
    0.16 * 2 = 0.32       // 小于1,则继续乘(与第三行相同,这样会一直循环执行下去)
    ...
    
    将相乘之后等结果的整数部分拼接起来,所以 0.29的 二进制表示:010010100011110101110000101000111...
    

所以,最终39.29的二进制表示为:100111.010010100011110101110000101000111...

第二步:科学计数法表示

100111.010010100011110101110000101000111... $$ 1.00111010010100011110101110000101000111... * 2^5 $$

第三步:存储

以float32为例来进行存储,用32位来存储浮点型

  • sign,用1位来表示浮点数正负,0表示正数;1表示负数。
  • exponent,用8位来表示共有256种(0~255),含正负值(-127 ~ 128)。例如:5想要存储到exponent位的话,需要让 5 + 127 = 132,再讲132转换二进制,存储到exponent。(132的二进制是:01000010)
  • fraction,存储小数点后的所有数据。

float64和float32类似,只是用于表示各部分的位数不同而已,其中:sign=1位exponent=11位fraction=52位,也就意味着可以表示的范围更大了。

results matching ""

    No results matching ""