`

计算机的二进制带符号运算为什么用0表示正数1表示负数

    博客分类:
  • Java
阅读更多

以8b为例对比如下:(谁能给我补补课,说说为什么是正0负1,按照我的理解应该是正1负0更符合人类的思维,前者是进行了一次技术上的mapping了)


正号:0
负号:1

原码:
+1 0 000 0001
-1 1 000 0001

反码:
+1 ...
-1 1 111 1110

补码:
+1 ...
-1 1 111 1111


1+(-1)=0

  0 000 0001
  1 111 1111
------------
10 000 0000  = (+0)


而如果反过来就会是这样的:

正号:1
负号:0

原码:
+1 1 000 0001
-1 0 000 0001

反码:
+1 ...
-1 0 111 1110

补码:
+1 ...
-1 0 111 1111


1+(-1)=0

1 000 0001
0 111 1111
------------
10 000 0000  = (溢出位 8b考虑为 +0)


20090601
相关链接:
http://dev.csdn.net/develop/article/17/17680.shtm


逆向推理:

先有正数运算,再有负数,才会产生有符号运算所遇到的问题。
按照离散数学的原理,需要解决的问题有两个:
1、负0怎样才能和正0具有相同的标志;
2、其他负数如何确定各自的标志;
3、运算规律是否可行;

下面给出我的推导过程及最后的公式,我觉得 原码和反码的转换公式要比以前我看到的教程简单很多。
一、拿二位10进制为例
可得排列组合(标志)为00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19 共计2*10^1 = 20 个数,为正数1~9 、 0 、和负数10个。(因为正数和0在负数概念出现以前已经确定,所以剩下的数为负数)。


二、拿二位2进制为例
同理有标志00 01 10 11,00为+0,01为+1,推理另两个标志对应的负数。

 


结论

同样的方法可以放到三位二进制 ,四位二进制等,表示为x位n进制可得到公式:
负数原码和补码的转换公式:
1v = -(n^(x-1)-v)
放到8位2进制即:

1v=-(2^7-v)


代入8位二进制即使
1000 0000 = - (2^7-0)= -128;
1000 0001 = -(2^7-1) = -127;
1000 0002 = -(2^7-2) = -126;
...
1111 1111 = -(2^7-(2^7-1)) = -1;

 

"-1就是减1嘛,想一想00000000减去1应该是多少呢,不够就借位,那就是11111111"

这句话同样体现了前提:不破坏先前的正数(包括0)的运算法则。

 

结:那些计算机教材写得真垃圾啊,就这么简单的问题搞锤子求反+1 ,基本上无逻辑可言。

结合离散等数学知识,这个问题是不是可以延伸到内存寻址等相关方面呢?

 

分享到:
评论
16 楼 janh 2007-07-22  
-1就是减1嘛,想一想00000000减去1应该是多少呢,不够就借位,那就是11111111
15 楼 birdjavaeye 2007-07-22  
补码数中的负数 不是原码表示法负数取反加1,是正数取反加1
14 楼 birdjavaeye 2007-07-22  
引用

一 确信你是对的?OXFF 是1111 1111 是-127 不是-1 -1的原码是 1000 0001 反码是 0111 1110 补码是 0111 1111 用16进制表示是 OX7F 是否你搞混了这几种编码 还是我没理解你的说法?
二 不明白你在说什么 正数 源码 反码 补码 都是本身 你说
”单字节有符号整数,正数部分的取值范围是0x00-0x7F。求补码时取反加1,对应0xFF-0x81。“不理解

补码数,x的相反数,就是x求反再加1
于是-1就等于 1取反再加1就是 00000001 -> 11111110 + 1 = 11111111
-(-1)就是-1取反再加1就是 11111111 -> 00000000 + 1 = 00000001
13 楼 birdjavaeye 2007-07-22  
补码中:
-1是11111111
于是1 + (-1)
  00000001
+ 11111111
----------
100000000 (保留8位)
  00000000 = 0

补码单字节一共有256个数,没有重复,10000000不是-0,是-128

楼主的设计按照 字节整体运算 的原则是错误的:
1是10000001,那么1+1应该是2,于是:
  10000001
+ 10000001
----------
100000010(保留8位)
  00000010(2还是-2?)
楼主把符号位0定义为负数,那这个肯定不是2了,矛盾
如果不用整体运算,把符号位单独提出来处理,那就复杂多了

所以,现实的选择只能是符号位0非负1负
而这么设计还有一个好处,就是简化无符号数和有符号数的转换:
           0x0 ~ 0x7F 0x80 ~ 0xFF
有符号补码:0 ~ 127    -128 ~ -1
无符号:    0 ~ 127    128 ~ 255
有一半的数是对应的,在已知某个有符号字节实际存放正数时,可以直接当做无符号数用,保持了一定的兼容
12 楼 jianfeng008cn 2007-06-07  
jianfeng008cn 写道
程序员一懒就用了 1 来表示 负 是说得通的
程序员一懒就用就用补码 好像没什么道理
反过来 带符号运算 不用补码可以吗?


解释下 反过来是 说 ”1表示正 0表示负“ 这种情况下 补码也是必需的
11 楼 jianfeng008cn 2007-06-07  
BirdGu 写道
单字节有符号整数,-1的表示应该是1111 1111 (0xFF),而不是0x7F。

单字节有符号整数,正数部分的取值范围是0x00-0x7F。求补码时取反加1,对应0xFF-0x81。所以所有负数的最高位都是1。



一 确信你是对的?OXFF 是1111 1111 是-127 不是-1 -1的原码是 1000 0001 反码是 0111 1110 补码是 0111 1111 用16进制表示是 OX7F 是否你搞混了这几种编码 还是我没理解你的说法?
二 不明白你在说什么 正数 源码 反码 补码 都是本身 你说
”单字节有符号整数,正数部分的取值范围是0x00-0x7F。求补码时取反加1,对应0xFF-0x81。“不理解
10 楼 qiezi 2007-06-07  
我记得哪看到过了,+0和-0。1000...0000表示+0,0000...0000表示-0,这样也是可以的,为了统一就用0000..0000表示了。

用补码好处是不管有无符号,+和-计算方法都一样,不过*和/还是要区分。
9 楼 BirdGu 2007-06-07  
单字节有符号整数,-1的表示应该是1111 1111 (0xFF),而不是0x7F。

单字节有符号整数,正数部分的取值范围是0x00-0x7F。求补码时取反加1,对应0xFF-0x81。所以所有负数的最高位都是1。

8 楼 jianfeng008cn 2007-06-07  
不仅仅是计算机 数学也一样 开始没有负数的概念,后来有需要了,就需要加个符号来表示负数,这就是个从没有到有的过程 这两符号的后面是数字
7 楼 jianfeng008cn 2007-06-07  
hey hey,

这个需求不恶心的,数学再发展,计算机科学也在发展,这是个很合理的需求。

再说一次,”思想性“,不要老在code的角度想这个问题,也许该看看探索这样的电影来综合下

程序员的思维。

6 楼 抛出异常的爱 2007-06-07  
jianfeng008cn 写道
再想了下 这个问题的其实是前提错掉了 ,按照人来的思维并不是 用1来表示正 就合理了
因为符号是处在和数字不同的层面上了 ,先有了无符号运算也是理所当然,后来要引入无符号运算,
自然得多一个符号出来,原来是没有的 现在需要一个 这就是 从无到有的过程 用1来表示"有" "0"来表示无
又回到了”理所当然“的路上,符号和数字不能在同一个层面上考虑,自然也不能拿数字的含义来表示
思考正负号了。
最近看到某处有人说中国人的二进制使用比西方早了4K多年,”易有太极,是生两仪,两仪生四象,四象生八卦,八卦定极凶,吉凶生大业“,被影响了,嘿嘿
附:生命中不能承受之轻 存在即真理 不停寻找 
真理是当时只有汇编,没有C这种高级语言
想要结构化编程都很困难
只好hack这种恶心的需求。
PS:汇编中的一个if else 写出来都会死人的。。。。
5 楼 jianfeng008cn 2007-06-07  
再想了下 这个问题的其实是前提错掉了 ,按照人来的思维并不是 用1来表示正 就合理了
因为符号是处在和数字不同的层面上了 ,先有了无符号运算也是理所当然,后来要引入无符号运算,
自然得多一个符号出来,原来是没有的 现在需要一个 这就是 从无到有的过程 用1来表示"有" "0"来表示无
又回到了”理所当然“的路上,符号和数字不能在同一个层面上考虑,自然也不能拿数字的含义来表示
思考正负号了。
最近看到某处有人说中国人的二进制使用比西方早了4K多年,”易有太极,是生两仪,两仪生四象,四象生八卦,八卦定极凶,吉凶生大业“,被影响了,嘿嘿
附:生命中不能承受之轻 存在即真理 不停寻找 
4 楼 jianfeng008cn 2007-06-07  
程序员一懒就用了 1 来表示 负 是说得通的
程序员一懒就用就用补码 好像没什么道理
反过来 带符号运算 不用补码可以吗?
3 楼 抛出异常的爱 2007-06-07  
负数+正数
二进制:
-1+1 =0

__11111111
+_00000001
---------------------
__00000000

如果象你说的那样
以前的程序的每个正数前面都 要加个1才能运算。。。。
程序员一懒就想到了用补码
2 楼 jianfeng008cn 2007-06-07  
本着“做不迷信、盲从的国人”的宗旨,继续追问

 

庄老大 能否说得具体点 举个例子之类的 哪些个规则反过来就遵守不了呢?
1 楼 庄表伟 2007-06-06  
因为先有无符号运算,后有带符号运算。

后来的规则,要兼容先有的规则。

相关推荐

    C++有符号二进制的加减运算

    在计算机中,整数可以被表示为二进制的正数或负数。对于负数,通常使用补码表示法。补码表示法是将一个正数的二进制形式按位取反(即0变成1,1变成0),然后加1,得到该数的负值表示。例如,十进制数-3的二进制补码...

    float浮点数二进制表示转换[源代码]

    1. 符号位(Sign Bit):1位,0代表正数,1代表负数。 2. 指数部分(Exponent):8位,采用偏移量(bias)表示,偏移量为127,即指数实际值 = 表示的二进制值 - 127。 3. 尾数部分(Fraction):23位,包含隐藏的1,...

    二进制多字节定点数运算

    二进制多字节定点数运算是计算机科学中一个基础且重要的概念,特别是在数字系统设计、嵌入式系统以及计算硬件领域。定点数是相对于浮点数而言的,它们在存储时固定占据一定的位宽,通常用于表示整数或带有小数点的...

    floatbin浮点数的二进制/16进制表示转换工具(附带源代码)

    1. 符号位:1位,0代表正数,1代表负数。 2. 指数:8位(单精度)或11位(双精度),存储的是偏移指数,而非实际指数值。 3. 尾数:23位(单精度)或52位(双精度),存储的是浮点数的小数部分,通常不包含隐藏的...

    程序员二进制计算器 v1.36

    当按二、八、十六进制输出时,是按其补码形式输出,最高位是符号位(正数为0、负数为1)。 所以此法可得到一个负数的补码表示。 (1)按二进制输出 %b或%B %b等价与%B。 %b 12 = 0b1100 %b 0xffffffff = 0b1111 ...

    计算机组成原理之带符号整数的表示和运算-原反补

    对于负数,其补码表示可以视为其绝对值的二进制表示取反后再加1。例如,负19的补码为1110 1100,这是从负19的原码1001 0011取反后得到1110 1100,再加1得到的。补码的运算规则简单且统一,无论加法还是减法,都可以...

    IEEE 745标准的32位二进制浮点数与十进制浮点数转换代码C#

    IEEE 745标准,也称为IEEE 754-1985,是国际电工委员会(IEEE)制定的一套关于浮点数运算的标准,它定义了如何用二进制表示单精度(32位)和双精度(64位)浮点数。 在32位的IEEE 745标准中,一个浮点数被分为三个...

    二进制和反射

    补码是计算机内部表示带符号整数(即可以表示正数和负数)的一种方法。它的主要优点是可以简化加法和减法运算,并且可以统一处理正数和负数。 #### 补码的计算方法 对于一个 n 位的二进制数,其补码的计算方法如下...

    进制浮点数与二进制浮点数之间的转换源代码

    其中,符号位0代表正数,1代表负数;指数部分是偏移量,用于表示实际的指数值;尾数部分是小数部分,通常以1.的形式表示,即1.s1s2...sm,其中s1到sm是尾数的二进制位。 二、十进制浮点数转二进制浮点数 1. 将十...

    二进制原码补码反码.docx

    例如:数字6在计算机中原码表示为:00000110,其中,第一个数字0是符号位,0表示正数,0000110是数字6的二进制数据表示。数字(-6)在计算机中原码表示为:10000110。 原码的缺陷 原码有一个很大的缺陷,那就是在带...

    十进制负数转换为二进制、八进制、十六进制的知识分享

    假设我们使用32位的int类型,那么+3的二进制形式为***,符号位为0表示这是一个正数。-3的补码则是在+3的基础上求取反码(每一位取反),然后加1得到。 将十进制的-3转换为二进制补码的步骤如下: 1. 将-3的绝对值3...

    计算机组成原理 第二章运算方法与运算器.ppt

    数的机器码表示在计算机中至关重要,无符号数只表示正数,而带符号数则可以表示正数和负数。机器码通常有原码、反码和补码三种形式,其中最高位作为符号位,0代表正,1代表负。 总的来说,这一章涵盖了数据的表示、...

    计算机组成原理与思维导图(二)第二章 数值数据的表示

    1. 二进制补码:计算机内部存储和运算均基于二进制,整数通常采用补码表示。补码是将正数的原码直接作为其补码,负数的原码除符号位外取反再加1。这种表示方式使得加法和减法操作可以统一处理,简化了硬件设计。 2....

    微型计算机原理及应用:第2章 微机运算基础.ppt

    本章主要探讨了计算机中不同数制的概念,包括进位计数制、数制间的转换、二进制编码、二进制数的运算、数的定点和浮点表示以及带符号数的表示法。 首先,进位计数制是计数的基本方式,其中基数表示数制中可用的数码...

    计算机组成与结构课件全第3章运算方法和运算部件.ppt

    二进制是最基础的,由0和1组成,八进制由0-7的数字表示,十进制是我们日常使用的计数系统,而十六进制则使用0-9和A-F来表示。不同数制之间的转换通过特定的规则进行,例如二进制转十进制可以通过权重求和,二进制转...

    浮点数的二进制编码(实验)

    1. **符号位**:浮点数的第一个位用于表示正负,0代表正数,1代表负数。在32位浮点数中,它位于最高位;在64位浮点数中,同样如此。 2. **指数部分**:接下来的部分表示指数,它是偏移量(bias),而非实际的指数值...

    数值型数据在计算机中的表示PPT学习教案.pptx

    1. **原码**:原码是最直观的表示方法,其中最高位(符号位)为0表示正数,为1表示负数。其余位(数值位)直接对应于该数值的二进制形式。例如,+85的原码为01010101,而-85的原码为11010101。对于0,有两种原码表示...

    计算机中的数和数制PPT学习教案.pptx

    在实际的计算机系统中,带符号数通常以补码形式存储和运算,这是因为补码可以方便地实现加法、减法,并且能够正确表示最大和最小的整数值,如在8位二进制系统中,可以表示-128到+127的整数范围。 总之,理解和掌握...

    补充计算机内的数据表示讲解优秀文档.ppt

    在计算机中,如果数值运算导致结果超过了可用位数能表示的最大值,就会从结果中减去一个“模”,这个模通常是2的位数次方减1,对于8位二进制来说,模是255。 在8位二进制原码中,可以表示的数值范围是+127到-127。...

    第三章---计算机的运算方法PPT课件.ppt

    计算机内部主要使用二进制(Binary)表示数据,因为二进制只包含0和1两个数字,易于电子元件的物理实现。然而,为了方便人类交流,我们通常使用十进制(Decimal)、八进制(Octal)和十六进制(Hexadecimal)这三种...

Global site tag (gtag.js) - Google Analytics