duanpanhuo0618 2016-04-10 23:53
浏览 450

golang:对于float64,fmt.Printf中的“%b”有什么作用?在float64中,二进制格式的Min次正规正整数是什么?

golang doc for Package fmt Floating-point and complex constituents says:

Floating-point and complex constituents:
%b decimalless scientific notation with exponent a power of two, in the manner of strconv.FormatFloat with the 'b' format, e.g. -123456p-78

and my test:

fmt.Printf("%b
", 1.0) 

the result:
4503599627370496p-52
what is it? your guess is mine!
so test this:

fmt.Printf("0b%b
", 255) //0b11111111

it is ok. so i think this is interesting and informative to share.

  • 写回答

1条回答 默认 最新

  • douyao4632 2016-04-10 23:53
    关注

    then i did some Research and after many hours of research with IEEE 754 binary representation; many inserting results came up:
    good point to start is:

    https://en.wikipedia.org/wiki/Double-precision_floating-point_format https://en.wikipedia.org/wiki/IEEE_floating_point

    then some test and results:

    package main
    import (
        "fmt"
        "math"
        "strconv"
           )
    
    func main() {
    fmt.Printf("0b%b
    ", 255) //0b11111111
    
    fmt.Printf("%b
    ", 1.0)               //4503599627370496p-52
    fmt.Printf("%#X
    ", 4503599627370496) //0X10000000000000
    //float64: 1.0 = binary: 0X3FF0000000000000
    //so 4503599627370496*2**-52 =("1"+"Fraction")*2**-52
    //=0X10 0000 0000 0000*2**-52=  2**52 * 2**-52 = 2**0 = 1=   significand
    //2**52=0x10 0000 0000 0000
    
    //1bit=sign 11bit=exponent-biased 52bit)=64 bit:
    fmt.Printf("%#X
    ", math.Float64bits(1.0)) //1.0=0X3FF0000000000000
    //Exp: 0x3FF=1023=E(0) :bias=1023 Emin=1 Emax=2046    Exp=pow(2,0x3FF - 1023)=pow(2,0)=1
    //significant: 1.mantisa (53bit nice!) 1.0000000000000
    
    //1.0000000000000002, the smallest number > 1
    fmt.Printf("%#X
    ", math.Float64bits(1.0000000000000002)) //0X3FF0000000000001
    
    // 1.0000000000000004, the next numer after 1.0000000000000002
    fmt.Printf("%#X
    ", math.Float64bits(1.0000000000000004)) //0X3FF0000000000002
    
    fmt.Printf("%#X
    ", math.Float64bits(2.0))  //0X4000000000000000
    fmt.Printf("%#X
    ", math.Float64bits(-2.0)) //0XC000000000000000
    
    // Min subnormal positive double
    fmt.Printf("%v
    ", math.Float64frombits(1))   //5e-324
    fmt.Printf("%#X
    ", math.Float64bits(5e-324)) //0X0000000000000001
    //Exp(2,-1022-52)=Exp(2,-1074)=5e-324
    
    //Max subnormal double
    fmt.Printf("%v
    ", math.Float64frombits(0x000fffffffffffff)) //2.225073858507201e-308
    
    fmt.Printf("%v
    ", math.Float64frombits(0X0000000000000000)) //0
    fmt.Printf("%v
    ", math.Float64frombits(0X8000000000000000)) //-0
    fmt.Printf("%v
    ", math.Float64frombits(0X7FF0000000000000)) //+Inf
    fmt.Printf("%v
    ", math.Float64frombits(0XFFF0000000000000)) //-Inf
    fmt.Printf("%v
    ", math.Float64frombits(0x7fffffffffffffff)) //NaN
    
    fmt.Printf("%#X
    %[1]b
    ", math.Float64bits(0.1)) //0X3FB 999999999999A
    //0 1111111011 1001100110011001100110011001100110011001100110011010
    
    fmt.Printf("%#X
    %[1]b
    ", math.Float64bits(0.2)) //0X3FC999999999999A
    //11111111001001100110011001100110011001100110011001100110011010
    
    fmt.Printf("%#X
    %[1]b
    ", math.Float64bits(0.3)) //0X3FD3333333333333
    //11111111010011001100110011001100110011001100110011001100110011
    fmt.Println(1.0 / 3.0) //0.3333333333333333
    //By default, 1/3 rounds down, instead of up like single precision,
    //because of the odd number of bits in the significand
    fmt.Printf("%#X
    %[1]b
    ", math.Float64bits(1.0/3.0)) //0X3FD5555555555555
    //11111111010101010101010101010101010101010101010101010101010101
    /*
       Given the hexadecimal representation 3FD5 5555 5555 555516,
         Sign = 0
         Exponent = 0x3FD = 1021
         Exponent Bias = 1023 (constant value)
         Fraction = 5 5555 5555 555516
         Value = 2(Exponent − Exponent Bias) × 1.Fraction // Note that Fraction must not be converted to decimal here
               = 2**−2 × (15 5555 5555 555516 × 2**−52)
               = 2**−54 × 15 5555 5555 555516
               = 0.333333333333333314829616256247390992939472198486328125
               ≈ 1/3
    */
    
    var f float64 = 0.1
    var bits uint64 = math.Float64bits(f) //IEEE 754 binary representation of f
    fmt.Printf("%#X %[1]b
    ", bits)
    //0X3FB999999999999A 11111110111001100110011001100110011001100110011001100110011010
    
    fmt.Printf("%b
    ", f) //7205759403792794p-56
    fmt.Printf("%b  %b
    ", 7205759403792794, -56)
    //11001100110011001100110011001100110011001100110011010  111000
    fmt.Println(len("11001100110011001100110011001100110011001100110011010"))
    //text search in this text=> 53 bit right side
    
    // 1 11111110101 100011110110001111100111100101011000111010000110011
    fmt.Printf("-: %b
    ", math.Float64bits(-0.1e+308)) // so left bit is sign bit
    //1 111111110101 100011110110001111100111100101011000111010000110011
    fmt.Printf("exp: %b
    ", math.Float64bits(+0.1e-308))
    //1 01110000001 010101110010011010001111110110101111
    // 11Exponent bits
    
    //  12345678901
    i, err := strconv.ParseInt("11111110101", 2, 64) //2037
    fmt.Println("E", i-1023)                         //1014
    
    fmt.Printf("%b
    ", 0.2) //7205759403792794p-55
    fmt.Printf("%b
    ", 0.3) //5404319552844595p-54
    
    n, err := fmt.Printf("%b %b
    ", 1.0, math.Float64bits(1.0))
    //4503599627370496p-52 11111111110000000000000000000000000000000000000000000000000000
    fmt.Println(n, err) //84 <nil>
    //no err
    fmt.Printf("'%[1]*.[2]*[3]f'
    ", 12, 4, 1234.1234) //'   1234.1234'
    

    }

    conclusion:
    %b for float shows only significand, done.
    this single line took many hours of my time!
    any comments are welcome, thanks.

    评论

报告相同问题?

悬赏问题

  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器