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  }