golang之数据转换
-
golang按位取反符号和异或符号都是^。
fmt.Printf("0x%X\n", 0xFF^0x55) var a uint8 = 0x55 fmt.Printf("%b\n", ^a)
要限定类型或位数,否则按int打印(打印负数)。
-
数据存储编解码
float32储存为4个字节,int16存储为两个字节,数据大小端怎样存储?
参考:edgexfoundry/device-sdk-go/pkg/commandvalue.go
借助io.Reader,int16和float32限定了数据存储的字节数。
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\n", usn) var mask uint16 = 0x1 var maskv uint16 = 0x0 usn = usn & (^mask) | mask fmt.Printf("0x%X\n", usn) usn = usn & (^mask) | maskv fmt.Printf("0x%X\n", usn) } }
-
float数据精度转换
参考:https://studygolang.com/articles/22284中浮点数比较
golang支持两种浮点float32和float64,众所周知,涉及浮点数比较或运算会遇到精度问题,具体要根据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) 因为函数错误时返回原来字符串,成功后返回正确的字符串,符合现实习惯
-
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)
这便是两种获得最大无符号数的方法了。
-
more
参考:
-
https://studygolang.com/articles/22284 golang不同类型比较
-
https://studygolang.com/articles/5567 golang最大无符号数