python和java之间对负数存储方式的不同

python和java之间对负数存储方式的不同

今天在leetcode上刷题时,发现python对于负数的二进制表示和其他有符号语言不同。

计算机如何存储负数

负数在计算机中是以补码的形式存在的,最高位是符号位

以-4为例 (32位整数)
print(bin(-4))
# -0b100
System.out.println(Integer.toBinaryString(-4)); 
// 11111111111111111111111111111100
当将其他语言的负数表示在python中转化为10进制时
print(int("11111111111111111111111111111100", 2))
# 原本-4 的表示就会变成 4294967292

也就是说python不会理解最高位为符号位这句话,将上面的二进制当做整数进行转化。正因为这种特性,在位运算时应格外注意负数的情况

解决办法
# 一个补码表示的负数想转化成python理解的负数
# 11111111111111111111111111111100 和 11111111111111111111111111111111 进行 异或运算
print(bin(0b11111111111111111111111111111100 ^ 0xffffffff))
# 0b11

# 再对上述结果进行取反操作 ~ (0变1 1变 0) 这样在计算中符号位会被Python理解为 -数
print(bin(~(0b11111111111111111111111111111100 ^ 0xffffffff)))
# -0b100 即转化成了 Python理解的 负数啦

def toPythonBinMinus(binnumber: int):
    # binnumber : without '0b' like 11111111111111111111111111111100
    # python 整数没有long这个概念就取最高位判断正数 负数表示
    if (str(binnumber)[0] == '1'):

        return bin(~(binnumber ^ 0xffffffff))
    else:
        return f"0b{binnumber}"
        

算法题

  1. 只出现一次的数字 II
class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        res = 0
        # 记录符号位的加和
        last_pin = 0
        for i in range(32):
            cur_sum = 0
            for num in nums:
                cur_sum += (num >> i) & 1

            # print(cur_sum)
            if cur_sum % 3 == 1:
                res |= 1 << i
            last_pin = cur_sum
        
        # 这里直接计算出的结果是补码表示的 python 会识别成正整数,所以如果是负数就需要转化成python 的转化方式
        #如果符号位加和不能被3整除 证明是 负数的结果 需要进行专门的转化
        return res if last_pin % 3 == 0 else ~(res ^ 0xffffffff)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值