zoukankan      html  css  js  c++  java
  • (转载)看C语言编码转换负数的二进制表示方法

    (转载)http://d1gua1.blog.163.com/blog/static/170185358201087104917801/?COLLCC=911213626&

    今天在看C语言编码转换时,既然对负数的二进制表示有些遗忘,查了下网上的资料,他们说的是个P!误人子弟!和大家讨论了下,贴出来已备在此遗忘:

    假设有一个 int 类型的数,值为5,那么,我们知道它在计算机中表示为:

    00000000 00000000 00000000 00000101

    5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

    现在想知道,-5在计算机中如何表示?

     

    在计算机中,负数以原码的补码形式表达。

    什么叫补码呢?这得从原码,反码说起。

     

    原码:一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码。

    比如 00000000 00000000 00000000 00000101 是 5的 原码。

              10000000 00000000 00000000 00000101 是 -5的 原码。

     

    反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。

    取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)

    比如:正数00000000 00000000 00000000 00000101 的反码还是 00000000 00000000 00000000 00000101

    负数10000000 00000000 00000000 00000101每一位取反(除符号位),得11111111 11111111 11111111 11111010。

    称:11111111 11111111 11111111 11111010 是 10000000 00000000 00000000 00000101 的反码。

    反码是相互的,所以也可称:

    10000000 00000000 00000000 00000101 和 11111111 11111111 11111111 11111010互为反码。

     

    补码:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.

    比如:10000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。

    那么,补码为:

    11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011


    所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。


    再举一例,我们来看整数-1在计算机中如何表示。

    假设这也是一个int类型,那么:


    1、得原码:10000000 00000000 00000000 00000001

    2、得反码:11111111 11111111 11111111 11111110(除符号位按位取反)

    3、得补码:11111111 11111111 11111111 11111111


    可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF

    主要知识点:

    (1)正数的反码和补码都与原码相同。
    (2)而负数的反码为对该数的原码除符号位外各位取反,
    负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1。

    下面是书上原文:

    原码表示法规定:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。
    反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
    补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
    正零和负零的补码相同,[+0]补=[-0]补=0000 0000B

     


    例子:

        unsigned char un_ch = 0xf7;
        char ch = un_ch;

        printf("%d\n", ch);

    这里我们取得了ch的补码=1111 0111。

    补码:1111 0111

    反码:1111 0110

    源码:1000 1001(除符号位外,其他的位都对反码进行取反)

    现在进行判断符号位为1,则表示负,然后1001表示9,最终得出ch为-9。

    这个过程和求-9在计算中的表示是一个逆过程。

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char** argv)
    {
        unsigned char un_ch = 0xf7;
        char ch = un_ch;
        int number1 = ch;  // 符号位会进行扩展
      int number2 = un_ch;  // 符号位不会进行扩展
    
        printf("%d\n", ch);
        printf("%d\n", number1);
        printf("%d\n", number2);
    
        return 0;
    }

    程序输出:

    -9

    -9

    247

    详见“基于C语言char与unsigned char的区别介绍”,将会详细unsigned char和char的区别。

  • 相关阅读:
    Go 语言简介(下)— 特性
    Array.length vs Array.prototype.length
    【转】javascript Object使用Array的方法
    【转】大话程序猿眼里的高并发架构
    【转】The magic behind array length property
    【转】Build Your own Simplified AngularJS in 200 Lines of JavaScript
    【转】在 2016 年做 PHP 开发是一种什么样的体验?(一)
    【转】大话程序猿眼里的高并发
    php通过token验证表单重复提交
    windows 杀进程软件
  • 原文地址:https://www.cnblogs.com/Robotke1/p/3074952.html
Copyright © 2011-2022 走看看