我需要将8位值符号扩展为12位。在C中,我可以这样做。我阅读了Apple的BinaryInteger协议文档,但它没有解释符号扩展到可变数量的位(我在Swift中也很新)。我怎么能在Swift中这样做,假设val是UInt8而numbits是12?
#define MASKBITS(numbits) ((1 << numbits) - 1)
#define SIGNEXTEND_TO_16(val, numbits) \
( \
(int16_t)((val & MASKBITS(numbits)) | ( \
(val & (1 << (numbits-1))) ? ~MASKBITS(numbits) : 0) \
))
答案 0 :(得分:2)
您可以使用Int8(bitPattern:)
转换给定的无符号
具有相同二进制表示的有符号值的值,
然后通过转换为Int16
进行符号扩展,再次进行无符号,最后进行截断
到给定的位数:
func signExtend(val: UInt8, numBits: Int) -> UInt16 {
// Sign extend to unsigned 16-bit:
var extended = UInt16(bitPattern: Int16(Int8(bitPattern: val)))
// Truncate to given number of bits:
if numBits < 16 {
extended = extended & ((1 << numBits) - 1)
}
return extended
}
示例:
for i in 1...16 {
let x = signExtend(val: 200, numBits: i)
print(String(format: "%2d %04X", i, x))
}
输出:
1 0000 2 0000 3 0000 4 0008 5 0008 6 0008 7 0048 8 00C8 9 01C8 10 03C8 11 07C8 12 0FC8 13 1FC8 14 3FC8 15 7FC8 16 FFC8
答案 1 :(得分:0)
在位流解析的上下文中,我有同样的问题。我需要将n位二进制补码值解析为Int32的代码。这是我的无条件解决方案:
jupyter notebook
以及显示如何使用该代码的单元测试功能:
extension UInt32 {
func signExtension(n: Int) -> Int32 {
let signed = Int32.init(bitPattern: self << (32 - n))
let result = signed >> (32 - n)
return result
}
}