github.com/jshiv/can-go@v0.2.1-0.20210224011015-069e90e90bdf/internal/reinterpret/reinterpret.go (about) 1 // Package reinterpret provides primitives for reinterpreting arbitrary-length values as signed or unsigned. 2 package reinterpret 3 4 // AsSigned reinterprets the provided unsigned value as a signed value. 5 func AsSigned(unsigned uint64, bits uint16) int64 { 6 switch bits { 7 case 8: 8 return int64(int8(uint8(unsigned))) 9 case 16: 10 return int64(int16(uint16(unsigned))) 11 case 32: 12 return int64(int32(uint32(unsigned))) 13 case 64: 14 return int64(unsigned) 15 default: 16 // calculate bit mask for sign bit 17 signBitMask := uint64(1 << (bits - 1)) 18 // check if sign bit is set 19 isNegative := unsigned&signBitMask > 0 20 if !isNegative { 21 // sign bit not set means we can reinterpret the value as-is 22 return int64(unsigned) 23 } 24 // calculate bit mask for extracting value bits (all bits except the sign bit) 25 valueBitMask := signBitMask - 1 26 // calculate two's complement of the value bits 27 value := ((^unsigned) & valueBitMask) + 1 28 // result is the negative value of the two's complement 29 return -1 * int64(value) 30 } 31 } 32 33 // AsUnsigned reinterprets the provided signed value as an unsigned value. 34 func AsUnsigned(signed int64, bits uint16) uint64 { 35 switch bits { 36 case 8: 37 return uint64(uint8(int8(signed))) 38 case 16: 39 return uint64(uint16(int16(signed))) 40 case 32: 41 return uint64(uint32(int32(signed))) 42 case 64: 43 return uint64(signed) 44 default: 45 // calculate bit mask for extracting relevant bits 46 valueBitMask := uint64(1<<bits) - 1 47 // extract relevant bits 48 return uint64(signed) & valueBitMask 49 } 50 }