将位串转换为有符号整数
Converting bit string to signed int
我编码和解码了一堆系数(与我之前的有关)。该过程基于 RLE,其中对一堆系数进行编码,运行时编码仅关注零。简而言之,这是原始数组:
[200, -145, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
编码为如下所示的二进制数据:
['000011001000', '11001>101101111<', '000010001110110011', '00010000111>1011110<', '00011000110011101', '000100011']
为了避免看起来像 -10010001 (-145) 的二进制数,我手动对负数执行了二进制补码(因为我找不到内置的方法)。本例中数字 (-145, -34) 的结果是 (101101111, 1011110)。
为了避免混淆,我在上面的数组中标记了它们,以解决此问题。
这被填充为可以被8整除(最后一个元素的开头插入了0),分成字节并写入文件。
当我读取文件时,我成功解码了大部分内容,并且系数的数量与开始的相同。负值出现问题:
[200, 367, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
我得到了 367 而不是 -145 而不是 -34 我得到了 94。
是否有任何内置方式(或任何一种方式)将位串转换为有符号值?我觉得这可以解决我的问题。我一直找不到办法,现在卡住了。
对于无符号数字,字长并不重要,因为前导零在那里没有意义。比如5=101
=0101
=00101
=0...0101
。但是,对于二进制补码,字长会有所不同,因为第一位表示负数。例如,-3=101
!= 0101
=5。如果你不知道第一个位是什么,你就无法判断这个数是不是负数。
您的编码似乎使用了可变字宽。由于您已经可以解码数字,因此您已经知道每个单词的宽度。
# these variables should be set by your decoder
# in this case we read -145 encoded as 101101111
width = 9
word = 367
# add this to your decoder to fix the sign
firstBit = word >> (width - 1)
if (firstBit == 1):
leadingOnes = (-1 << width)
word = leadingOnes | word
同样可以在没有分支的情况下在单个语句中完成,但我认为这对于 CPython 来说平均来说可能更慢,而且可读性肯定更差。
word |= -(word >> (width - 1)) << width
当然你必须确保非负数是用前导 0
编码的,这样你就可以将它们与负数区分开来。
我编码和解码了一堆系数(与我之前的
[200, -145, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
编码为如下所示的二进制数据:
['000011001000', '11001>101101111<', '000010001110110011', '00010000111>1011110<', '00011000110011101', '000100011']
为了避免看起来像 -10010001 (-145) 的二进制数,我手动对负数执行了二进制补码(因为我找不到内置的方法)。本例中数字 (-145, -34) 的结果是 (101101111, 1011110)。 为了避免混淆,我在上面的数组中标记了它们,以解决此问题。
这被填充为可以被8整除(最后一个元素的开头插入了0),分成字节并写入文件。
当我读取文件时,我成功解码了大部分内容,并且系数的数量与开始的相同。负值出现问题:
[200, 367, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
我得到了 367 而不是 -145 而不是 -34 我得到了 94。
是否有任何内置方式(或任何一种方式)将位串转换为有符号值?我觉得这可以解决我的问题。我一直找不到办法,现在卡住了。
对于无符号数字,字长并不重要,因为前导零在那里没有意义。比如5=101
=0101
=00101
=0...0101
。但是,对于二进制补码,字长会有所不同,因为第一位表示负数。例如,-3=101
!= 0101
=5。如果你不知道第一个位是什么,你就无法判断这个数是不是负数。
您的编码似乎使用了可变字宽。由于您已经可以解码数字,因此您已经知道每个单词的宽度。
# these variables should be set by your decoder
# in this case we read -145 encoded as 101101111
width = 9
word = 367
# add this to your decoder to fix the sign
firstBit = word >> (width - 1)
if (firstBit == 1):
leadingOnes = (-1 << width)
word = leadingOnes | word
同样可以在没有分支的情况下在单个语句中完成,但我认为这对于 CPython 来说平均来说可能更慢,而且可读性肯定更差。
word |= -(word >> (width - 1)) << width
当然你必须确保非负数是用前导 0
编码的,这样你就可以将它们与负数区分开来。