深入浅出golangGolang 入门资料+笔记Go

golang快速入门[8.3]-深入理解IEEE754浮点数

2020-03-24  本文已影响0人  唯识相链2

前文

前言

        var f1 float64 = 0.3        var f2 float64 = 0.6        fmt.Println(f1 + f2)

IEEE-754 如何存储浮点数

| 基本的10进制数字 | 科学计数法表示         | 指数表示        |     系数     | 底数 |    指数   |     小数  ||----------------|---------------------|----------------|-------------|------|----------|----------|| 700            | 7e+2                | 7 * 10^2       | 7           | 10   | 2        | 0        || 4,900,000,000  | 4.9e+9              | 4.9 * 10^9     | 4.9         | 10   | 9        | .9       || 5362.63        | 5.36263e+3          | 5.36263 * 10^3 | 5.36263     | 10   | 3        | .36263   || -0.00345       | 3.45e-3             | 3.45 * 10^-3   | 3.45        | 10   | -3       | .45      || 0.085          | 1.36e-4             | 1.36 * 2^-4    | 1.36        | 2    | -4       | .36      |
| 精度              | 符号位  |  指数位     |  小数位        |偏移量||------------------|--------|------------|---------------|------|| Single (32 Bits) | 1 [31] | 8 [30-23]  | 23 [22-00]    | 127  || Double (64 Bits) | 1 [63] | 11 [62-52] | 52 [51-00]    | 1023 |
| 符号位 | 指数位(123)    | 小数位 (.36)                  ||------|----------------|------------------------------|| 0    | 0111 1011      | 010 1110 0001 0100 0111 1011 |

小数位的计算

| Bit | Value   | Fraction  | Decimal          | Total            ||-----|---------|-----------|------------------|------------------|| 2   | 4       | 1⁄4       | 0.25             | 0.25             || 4   | 16      | 1⁄16      | 0.0625           | 0.3125           || 5   | 32      | 1⁄32      | 0.03125          | 0.34375          || 6   | 64      | 1⁄64      | 0.015625         | 0.359375         || 11  | 2048    | 1⁄2048    | 0.00048828125    | 0.35986328125    || 13  | 8192    | 1⁄8192    | 0.0001220703125  | 0.3599853515625  || 17  | 131072  | 1⁄131072  | 0.00000762939453 | 0.35999298095703 || 18  | 262144  | 1⁄262144  | 0.00000381469727 | 0.3599967956543  || 19  | 524288  | 1⁄524288  | 0.00000190734863 | 0.35999870300293 || 20  | 1048576 | 1⁄1048576 | 0.00000095367432 | 0.35999965667725 || 22  | 4194304 | 1⁄4194304 | 0.00000023841858 | 0.35999989509583 || 23  | 8388608 | 1⁄8388608 | 0.00000011920929 | 0.36000001430512 |

go语言显示浮点数 - 验证之前的理论

package mainimport (    "fmt"    "math")func main() {    var number float32 = 0.085    fmt.Printf("Starting Number: %f\n\n", number)    // Float32bits returns the IEEE 754 binary representation    bits := math.Float32bits(number)    binary := fmt.Sprintf("%.32b", bits)    fmt.Printf("Bit Pattern: %s | %s %s | %s %s %s %s %s %s\n\n",        binary[0:1],        binary[1:5], binary[5:9],        binary[9:12], binary[12:16], binary[16:20],        binary[20:24], binary[24:28], binary[28:32])    bias := 127    sign := bits & (1 << 31)    exponentRaw := int(bits >> 23)    exponent := exponentRaw - bias    var mantissa float64    for index, bit := range binary[9:32] {        if bit == 49 {            position := index + 1            bitValue := math.Pow(2, float64(position))            fractional := 1 / bitValue            mantissa = mantissa + fractional        }    }    value := (1 + mantissa) * math.Pow(2, float64(exponent))    fmt.Printf("Sign: %d Exponent: %d (%d) Mantissa: %f Value: %f\n\n",        sign,        exponentRaw,        exponent,        mantissa,        value)}
Starting Number: 0.085000Bit Pattern: 0 | 0111 1011 | 010 1110 0001 0100 0111 1011Sign: 0 Exponent: 123 (-4) Mantissa: 0.360000 Value: 0.085000

经典问题:如何判断一个浮点数其实存储的是整数

func IsInt(bits uint32, bias int) {    exponent := int(bits >> 23) - bias - 23    coefficient := (bits & ((1 << 23) - 1)) | (1 << 23)    intTest := (coefficient & (1 << uint32(-exponent) - 1))    fmt.Printf("\nExponent: %d Coefficient: %d IntTest: %d\n",        exponent,        coefficient,        intTest)    if exponent < -23 {        fmt.Printf("NOT INTEGER\n")        return    }    if exponent < 0 && intTest != 0 {        fmt.Printf("NOT INTEGER\n")        return    }    fmt.Printf("INTEGER\n")}
Starting Number: 234523.000000Bit Pattern: 0 | 1001 0000 | 110 0101 0000 0110 1100 0000Sign: 0 Exponent: 144 (17) Mantissa: 0.789268 Value: 234523.000000Exponent: -6 Coefficient: 15009472 IntTest: 0INTEGER
exponent := int(bits >> 23) - bias - 23
coefficient := (bits & ((1 << 23) - 1)) | (1 << 23)Bits:                   01001000011001010000011011000000(1 << 23) - 1:          00000000011111111111111111111111bits & ((1 << 23) - 1): 00000000011001010000011011000000
bits & ((1 << 23) - 1): 00000000011001010000011011000000
(1 << 23):              00000000100000000000000000000000
coefficient:            00000000111001010000011011000000
exponent:                     (144 - 127 - 23) = -6
1 << uint32(-exponent):       000000
(1 << uint32(-exponent)) - 1: 111111

coefficient:                 00000000111001010000011011000000
1 << uint32(-exponent)) - 1: 00000000000000000000000000111111
intTest:                     00000000000000000000000000000000

扩展阅读:概念:Normal number and denormal (or subnormal) number

In computing, a normal number is a non-zero number in a floating-point representation which is within the balanced range supported by a given floating-point format: it is a floating point number that can be represented without leading zeros in its significand.

扩展阅读:概念:精度

总结

参考资料

喜欢本文的朋友欢迎点赞分享~

image

唯识相链启用微信交流群(Go与区块链技术)

欢迎加微信:ywj2271840211

上一篇 下一篇

猜你喜欢

热点阅读