• golang之数据转换


    1. golang按位取反符号和异或符号都是^

    fmt.Printf("0x%X
    ", 0xFF^0x55)
    var a uint8 = 0x55
    fmt.Printf("%b
    ", ^a)

    要限定类型或位数,否则按int打印(打印负数)。

    1. 数据存储编解码

    float32储存为4个字节,int16存储为两个字节,数据大小端怎样存储?

    参考:edgexfoundry/device-sdk-go/pkg/commandvalue.go

    借助io.Readerint16float32限定了数据存储的字节数。

    func encodeValue(value interface{}) ([]byte, error) {
        buf := new(bytes.Buffer)
        err := binary.Write(buf, binary.LittleEndian, value)
        return buf.Bytes(), err
    }
    
    func decodeValue(reader io.Reader, value interface{}) error {
        err := binary.Read(reader, binary.LittleEndian, value)
        return err
    }
    
    func float32Value(buf []byte) (value float32, err error) {
        err = decodeValue(bytes.NewReader(buf), &value)
        return value, err
    }
    
    func int16Value(buf []byte) (value int16, err error) {
        err = decodeValue(bytes.NewReader(buf), &value)
        return value, err
    }
    
    func uint16Value(buf []byte) (value uint16, err error) {
        err = decodeValue(bytes.NewReader(buf), &value)
        return value, err
        }
    
    func main(){
        var ff float32 = 100.5
        ffb, err := encodeValue(ff)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(ffb)
        }
    
        fmt.Println("------------------")
        ffn, err := float32Value(ffb)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(ffn)
        }
    
        fmt.Println("----------------------------------")
        var us uint16 = 0xFFF1
        usb , err := encodeValue(us)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(usb)
        }
        fmt.Println("------------------")
        usn, err := uint16Value(usb)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Printf("0x%X
    ", usn)
            var mask uint16 = 0x1
            var maskv uint16 = 0x0
            usn = usn & (^mask) | mask
            fmt.Printf("0x%X
    ", usn)
            usn = usn & (^mask) | maskv
            fmt.Printf("0x%X
    ", usn)
        }
    }
    1. float数据精度转换

    参考:https://studygolang.com/articles/22284中浮点数比较

    golang支持两种浮点float32float64,众所周知,涉及浮点数比较或运算会遇到精度问题,具体要根据golang实现IEEE 754的情况定。

    默认情况下,float32精度是小数后7位,float64精度是小数后15位。浮点数比较时取精度范围内的数据,范围外根据存储情况五舍六入(5实际存储时可能是5.9舍,可能是5.99入)。

    package main
    
    import (
        "fmt"
    )
    
    func main(){
        var a float32 =     1.0000001
        var b float32 =     1.00000001
        var bb float32 =    1.00000005
        var bbb float32 =   1.00000006
        var c float32 =     1.00000000000001
    
        fmt.Println(a == b) // false
        fmt.Println(a == bb) // false
        fmt.Println(b == bb) // true
        fmt.Println(b == c) // true
        fmt.Println(bb == c)// true
        fmt.Println(a == bbb) // true
        fmt.Println(bb == bbb) // false
    }

    小数点后保留两位小数:

    func updateFloatPrecision(sf string, pre int, bitSize int) (sfp string, err error){
        ff, err := strconv.ParseFloat(sf, bitSize)
        if err != nil {
            return sf, err
        }
        sfp = strconv.FormatFloat(float64(ff), 'f', pre, bitSize)
        return sfp, nil
    }
    
        sfp := "-3.1415926"
        sfp, err := updateFloatPrecision(sfp, 2, 32)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(sfp)
        }
    或
    sfp, _ :=updateFloatPrecision(sfp, 2, 32)
    fmt.Prinln(sfp)
    因为函数错误时返回原来字符串,成功后返回正确的字符串,符合现实习惯
    1. golang最大数值

    math包定义了最大数值。https://golang.google.cn/pkg/math/

    Floating-point limit values. Max is the largest finite value representable by the type. SmallestNonzero is the smallest positive, non-zero value representable by the type.
    const (
        MaxFloat32             = 3.40282346638528859811704183484516925440e+38  // 2**127 * (2**24 - 1) / 2**23
        SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23)
    
        MaxFloat64             = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52
        SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52)
    )
    Integer limit values.
    const (
        MaxInt8   = 1<<7 - 1
        MinInt8   = -1 << 7
        MaxInt16  = 1<<15 - 1
        MinInt16  = -1 << 15
        MaxInt32  = 1<<31 - 1
        MinInt32  = -1 << 31
        MaxInt64  = 1<<63 - 1
        MinInt64  = -1 << 63
        MaxUint8  = 1<<8 - 1
        MaxUint16 = 1<<16 - 1
        MaxUint32 = 1<<32 - 1
        MaxUint64 = 1<<64 - 1
    )

    参考:golang最大无符号数

    对于不确定位数的uint,最大的无符号数和-1在位数上是一样的。但是,无论是 const MaxUint uint = -1 // Error: negative value , 还是const MaxUint uint = uint(-1) // Error: negative value,都不能通过编译,原因自然是类型与范围的冲突了。但运行时,-1的值确实可以传递给无符号是,怎么通过编译,又将这个值传给无符号数呢?可以

    var u uint
    var v = -1
    u = uint(v)

    这样就搞定了。另一种方法就是对0取反。区别是,0取反后,是无限多个1,那么有限范围的uint去接它,显然会被编译器认为损失精度了。办法是先构造出确定位数的0,再取反,如下:

    const MaxUint = ^uint(0)

    这便是两种获得最大无符号数的方法了。

    1. more


    参考:

      1. https://studygolang.com/articles/22284 golang不同类型比较

      2. https://studygolang.com/articles/5567 golang最大无符号数

  • 相关阅读:
    翻转单词顺序
    java layout 表格项增加、删除、修改
    Hadoop学习之HBase
    protected的一些功能
    hdu4431 Mahjong
    kendo ui gird温馨提示(使用本地数据) 一个
    TOP计划猿10最佳实践文章
    Java高级应用(一个)-文件夹监控服务
    BSD介绍
    获取编译学习笔记 (十三)—— 外部中断
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/12006420.html
Copyright © 2020-2023  润新知