Float32 & Float64 值的计算方式

2022-06-03  本文已影响0人  Sun东辉

遵循 IEEE 754 标准(所有新式 CPU 都支持该标准),浮点数在计算机中的存储,分为三部分:

  1. 符号位,区分正数还是负数。
  2. 指数部分, float32 在 [0,255]区间内, Float64 在 [0,2047]区间内。
  3. 有效数字部分,在[0,1]区间内。

浮点数的值 = 符号位指数部分的值有效数字部分的值

Float32 数值的具体的计算过程如下:

package main

import (
    "fmt"
    "github.com/imroc/biu"
    "math"
    "strconv"
    "strings"
)

func main() {
    var i float32 = 99.99
    exponentLen := 8           // 指数部分的长度
    var middleware int64 = 127 // 中间数
    // 获取完整的二进制存储值
    str := biu.ToBinaryString(math.Float32bits(i))
    fmt.Println("str: ", str)
    // 只保留 0101 值
    newStr := strings.ReplaceAll(str[1:len(str)-1], " ", "")
    fmt.Println("newStr: ", newStr)
    // 数值切分逻辑

    sign := newStr[0:1]
    exponent := newStr[1 : 1+exponentLen]
    fraction := newStr[1+exponentLen:]
    fmt.Println("sign: ", sign)
    fmt.Println("exponent: ", exponent)
    fmt.Println("fraction: ", fraction)
    // 指数部分值计算逻辑
    decimalExponent, _ := strconv.ParseInt(exponent, 2, 32)
    fmt.Println("decimalExponent: ", decimalExponent)
    exponentValue := 1 << (decimalExponent - middleware)
    fmt.Println("exponentValue: ", exponentValue)
    // 有效数字部分计算逻辑
    decimalFraction, _ := strconv.ParseInt(fraction, 2, 32)
    fmt.Println("decimalFraction: ", decimalFraction)
    dividend := 1 << (len(newStr) - 1 - exponentLen)
    fractionValue := float64(decimalFraction)/float64(dividend) + 1
    fmt.Println("fractionValue: ", fractionValue)

    fmt.Println(fractionValue * float64(exponentValue))
}

// 打印结果
/*          
str:  [01000010 11000111 11111010 11100001]
newStr:  01000010110001111111101011100001
sign:  0
exponent:  10000101
fraction:  10001111111101011100001
decimalExponent:  133
exponentValue:  64
decimalFraction:  4717281
fractionValue:  1.562343716621399
99.98999786376953
*/

对于 Float64 数值,只需要

上一篇 下一篇

猜你喜欢

热点阅读