补码0-0

问题描述:

为了背景,我试图计算一个存储在常量内存中的IP数据包的校验和(不能修改它)。在执行校验和之前,我应该假装数据包中的现有校验和为0.不是将所有数据复制到临时缓冲区,而是存储0,我想对整个数据包执行校验和,然后减去来自结果的现有校验和。补码0-0

要做到这一点,我一直在寻找一种补充版本的减法,我找到了here。不幸的是,如果我用这个,并且从0减去0,我得到0x1111而不是预期的0:

  1. 转换0的补数:[1111]
  2. 接下来,我们添加0:[1111]
  3. 没有溢出位,所以我们就大功告成了...

我本来期望0 - 0 0 - 我缺少什么?

+8

补码有两种表示0:+0(0000)和-0(1111)。 –

+1

补货会给你买什么? –

+0

假设您不想使用您计算的新校验和,您可以保存当前校验和,将其设置为0,计算校验和,然后将原始数据恢复,而不是复制整个缓冲区。 – clcto

你不需要减去。

如果校验和有效,计算整个数据包的校验和(包括校验和)应该给你0.如果结果不是0,数据包就会被破坏。

这是路由器如何验证校验和。

我建议阅读的补本教程

https://courses.cs.vt.edu/csonline/NumberSystems/Lessons/SubtractionWithOnesComplement/index.html

我觉得这是很容易:

0000 - 0000 = 0000 + 1111 = 1111 

当最后1111是在一个人的补码形式,我们知道,这是具有领先1的负数。 最后的操作是人的补充(1111)。

最终答案是- 0000。 正如你所知道的一个人的补数计算是有两种形式 呈现零0