原码、反码、补码再探

1|0原码、反码、补码与 memset 再探

1|1概述

三个计算机用来表达负数的形式。

  • 原码
    • 通过第一位的 0 来直接表示正数,1 来直接表示负数。
    • 然而计算机并不用这种方式。
  • 反码
    • 即把要表示的负数的绝对值对应的二进制全部取反来表示。
    • 坏处是 0 有两种表达方式,全 0 和全 1 ,所以也不常用。
  • 补码
    • 即把要表示的负数的绝对值对应的二进制全部取反后再加一来表示。
    • 计算机用这种方式就很方便。

1|2转换

1|0转出

对于 57

57 的二进制:

0011 1001

  • 原码
    • 1011 1001
  • 反码
    • 1100 0110
  • 补码
    • 1100 0111

1|0转回

  • 原码 1011 1001
    • 0011 1001=57
  • 反码 1100 0110
    • 取反加一
    • 27+26+22+21=58
    • 58+1=57
  • 补码 1100 0111
    • 直接取反
    • 27+26+22+21+20=57

1|3计算

计算机计算二进制减法:

6657=9

67=0100 0010

57=1100 0111

   0100 0010

+1100 0111

 10000 1001

这个数字溢出了 1 位,所以去低位数的 8 位,得到的答案就是 0000 1001,也就是十进制下的 9

补码的设计使得计算机可以化减为加。

但谈论补码时,务必要确定总位数,如 char 类型的 1100 0111int 类型的 00 1100 0111 表示的可不是同一个数字。

1|4memset

到这里就可以解释为什么memset只对于 10 有一一对应的赋值。

首先 memset 按字节赋值,即对于每个字节赋予你给定的值。

对于 0 ,在补码体系下,每个字节都是 0,所以对应。

对于 1,补码体系下,对于一个字节 1111 1111,每个字节都是 1111 1111,所以对应。

依照原理,memset 0xff1111 1111 自然也可以把数组初始化为 1

并且,memset 对于 intlong 并不能赋值到最大值,就比如 int 有四个字节,它的最大值是

0111 1111 1111 1111 1111 1111 1111 1111

0X7FFFFFFF

然而对于 memset 只能对每个字节赋相同值的特性(每 8 位二进制,每 2 位十六进制),肯定不能让这种四个字节中有一个字节不同的值赋出来。

当然,对于刚好是一个字节的char 类型数组,memset则可以赋值任意一一对应的值。


__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17871394.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示