zoukankan      html  css  js  c++  java
  • 计算机基础之原码,反码,补码

    自从从学校出来当了 Java 码农后,离这些经典又重要的计算机基础知识越来越远了。。。现在的情况是,连原码,反码,补码都傻傻分不清了!
    最近在对 PHP 代码使用 Java 重构时,遇到了这么个问题:之前的 PHP 程序员在存储客户端 IPv4 地址时,是将获取到的点分十进制 IPv4 地址转换成了相应的整数存入数据库的,这么做的好处嘛就是节省空间,方便索引。“将点分十进制的 IPv4 地址转换成整数”,这在 PHP 中很简单,原生 API 支持,API 文档在此!但对于 Java 程序员来说就不是这么简单的了,因为 Java 并没有提供原生 API 的支持!
    那么,现在只能考虑自己使用 Java 实现了:
    首先,需要弄清楚 PHP 中 ip2long($ip) 的实现原理,经过参考某位仁兄的写的博客PHP: 详解ip2long和long2ip,基本上就了解其原理了。原理其实很简单:就是把点分十进制的 IPv4 地址字符串,按照其二进制形式放入一个四字节的整型变量中即可!上面那位仁兄博客里有用 C 语言实现了下 PHP 方法 ip2long(),直接使用逻辑左移即可,但输出的一正一负的结果却引起了我的兴趣(因为不理解嘛)。于是,我在例子上又加了一行:

    #include <stdio.h>
    
    int main(int argc, char** argv){
    	unsigned int ip_long = (157 << 24) | (23 << 16) | (56 << 8) | 90;
    	printf("%x
    ", ip_long);
    	printf("%u
    ", ip_long);
    	printf("%d
    ", ip_long);
    
    	return 0;
    }
    

    即输出整形变量 ip_long 的十六进制形式,运行结果如下:

    9d17385a
    2635544666
    -1659422630
    

    那么,该怎么解释着三行输出呢?此时便想起了原码,反码,补码的转换规则:

    1. 正数的原码,反码,补码都一样;
    2. 负数原码符号位不变,数值位按位取反的结果就是反码;
    3. 负数的反码加一便是其补码;
    4. 计算机中存储的数字的二进制形式是该数字的补码形式;

    也就是说:数字 A 在计算机中存储的二进制形式是:数字 A 转换为二进制形式 B,此时 B 就是数字 A 的原码,再将 B 转换为反码 C,最后将反码 C 转换为补码 D,补码 D 就是数字 A 最终在计算机中的二进制形式。验证下这个说法,十六进制数 9d17385a 转换为二进制形式是:10011101000101110011100001011010

    1. 将变量 ip_long 解释为无符号整数,则 ip_long 即为正整数,则其原码,反码,补码都一样,所以推导出的 ip_long 的原码就是:10011101000101110011100001011010,转换为十进制即:2635544666,验证正确;
    2. 将变量 ip_long 解释为有符号整数,则从补码 10011101000101110011100001011010 的第一位即符号位为 1 可知 ip_long 是一个负数,再把补码 10011101000101110011100001011010 转换为其原码可得到原码:11100010111010001100011110100110,先不算符号位的 1,可得此数的绝对值的二进制是:1100010111010001100011110100110,转换为十进制是:1659422630,因为它是负数,所以最终结果是:-1659422630,验证正确;

    参考

    1. PHP: 详解ip2long和long2ip
    2. Java ip2long equivalent
    3. 在线进制转换
  • 相关阅读:
    PIL.Image 与 base64互转
    python pytorch ssd网络
    mysql 的左连接、又连接、内连接详细介绍
    base64图片数据类型转numpy的ndarray矩阵类型数据
    kettle学习资料
    kettle 连接 mysql8.0 报错的解决办法 org.pentaho.di.core.exception.KettleDatabaseException: Error occurred while trying to connect to the database Error connecting to database: (using class org.gjt.mm.mysql.
    python pandas 自动生成批量测试数据插入数据库 mysql
    finereport点击图表钻取到明细表包括参数传递
    finereport连接mysql8.0的解决办法
    kettle7.0 Windows10 mysql8.0 连接mysql驱动报错,问题解决
  • 原文地址:https://www.cnblogs.com/craftsman-gao/p/7019629.html
Copyright © 2011-2022 走看看