zoukankan      html  css  js  c++  java
  • 整数的内存表示---记录一道题目

      最近面试,面试官问我的竟然都是程序员宝典里面的C++问题,这里记录一下看程序员宝典过程中遇到的问题,当做一种日记吧。整数无非是负数,正数和0,他们在内存中的二进制表示和原码、反码、补码息息相关。

    一、原码、反码、补码的定义

    1.原码

    正数的原码的符号位为0,负数的原码符号位为1,其他位则表示为是其绝对值的二进制形式。记录几个例子:

    X=+1011011       [X]原码=01011011
    Y=-1011011         [Y]原码=11011011
    [+1]原码=00000001     [-1]原码=10000001
    [+127]原码=01111111     [-127]原码=11111111

    例如对于-127要求其原码,首先由于它是负数所以符号位是1,然后其绝对值为127所对应的二进制是1111111,所以-127的原码是11111111。

    原码表示的整数范围是:-(2n-1-1)~+(2n-1-1),其中n为机器字长。则:8位二进制原码表示的整数范围是-127~+127。16位二进制原码表示的整数范围是-32767~+32767。

    2.反码

    对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。记录例子,当机器字长为8位二进制数时:
    X=+1011011 [X]原码=01011011   [X]反码=01011011
    Y=-1011011 [Y]原码=11011011   [Y]反码=10100100
    [+1]反码=00000001    [-1]反码=11111110
    [+127]反码=01111111    [-127]反码=10000000

    反码表示的整数范围与原码相同。

    3.补码

    正数的补码与其原码相同,负数的补码为其反码在最低位加1。记录几个例子:

    (1) X=+1011011 (2) Y=-1011011
    (1) 根据定义有: [X]原码=01011011        [X]补码=01011011
    (2) 根据定义有: [Y]原码=11011011        [Y]反码=10100100    [Y]补码=10100101
    补码表示的整数范围是-2n-1~+(2n-1-1),其中n为机器字长。则:8位二进制补码表示的整数范围是-128~+127(-128 表示为10000000,无对应的原码和反码)。16位二进制补码表示的整数范围是-32768~+32767。当运算结果超出这个范围时,就不能正确表示数了,此时称为溢出。


    最后记录一下程序员宝典上的这道题目:

    有两个变量a和b,不用if,?:,switch或者其他判断语句,找出两个数中比较大的。

    其中有一个方案是:

    int c = a - b;
    char *strs[2] = {"a Large", "b Large"};
    c = unsigned(c) >> (sizeof(int) * 8 - 1);
    

     这里的思路就是计算a-b,然后判断c的符号位是0还是1。是0就代表a大。由于c是有符号整型这时候要右移31位获得符号位,如果此时c是负数那么右移之后左边补的是1,所以最终c的取值不在是0,1。所以需要将c转为无符号整型,这样右移之后左边补的是0,最终c保存的就是1~31位是0,第0位保存的是符号位,所以c的取值要不是0,要不是1。

  • 相关阅读:
    mysql 8 查询报错(sql_mode=only_full_group_by)
    docker安装mysql8版本后 客户端连接出现client does not support authentication...
    docker常用命令
    查看tomcat日志相关Linux命令
    java项目部署到linux服务器涉及的命令
    ehcache与redis对比
    JS中调用BigDecimal处理金额
    thymeleaf模板 th:href 踩坑
    汇总一些绝对有价值的解决方案,边学习边收集
    spring注解总结,spring注解大全
  • 原文地址:https://www.cnblogs.com/Key-Ky/p/4432308.html
Copyright © 2011-2022 走看看