一道JAVA面试题引起的基础回顾!
请记住一些约定:(这是很底层的东西,也是计算机的基础知识,不要拿十万个为什么来自问或反问?因为回答这些问题就跟你问“1+1为什么等于2”一样的让人抓狂!)
计算机的语言:只有二进制,那永远是0和1,没有0和1的话,全世界的显示器都将熄灭了!
再底层次说一点:
在模拟电路里,1代表开关的接通,0代表开关的断开,这样就形成原始的电信号。自然界有很多的自然参数(比如声,光,磁,压力,湿度,温度,微波)我们故且叫它自然信号,可以通过相应的信号感测器将这些具有自然特性的信号转换成模拟自然参数和状态的电信号;也就是信息领域里研究的模拟信号;
在数字电路里,0代表低电平,1代表高电平,如此就是一个脉冲,脉冲有上升沿(0—>1瞬间)和下降沿(1—>0瞬间),利用上升沿和下降沿我们可以做很多事情,比如用保持寄存器(RS)来保存其状态。。。如此的一个个脉冲形成一种信号,也就是常说的数字信号,现在的计算机领域里多研究的是数字信号。我们知道通过模/数(A/D)和数/模(D/A)可以实现着二信号之间的转换。
计算机正是利用这样的信号来发挥它的超能力,理解了0和1的本质就不会对二进制有什么好奇了!
(不再作任何说明,下面所有的例子以JAVA为例讲解。)
Q1:为什么还会有八进制、十进制、十六进制?
其实进制是多少都无所谓,都是一种计数的方式和手段,只不过我们人类的世界里已经习惯了十进制的计数方式,习惯用作惯例,惯例形成规则,竟而形成标准和规范,所以我们在编程中常用的还是10进制计数方式。
不过数据在计算机中最终以二进制的形式存在,所以有时候使用二进制,可以更直观地解决问题。但二进制数真TM的太长了。比如JAVA中int 类型占用4个字节*8=32位。INT类型100的二进制表示为:
0000 0000 0000 0000 0110 0100
面对这么长的数进行思考或操作,没有人会爱上她。因此C/C++,JAVA 没有提供在代码里直接写二进制数的方法,但提供了直接写8进制和16进制支持。
用16进制或8进制可以解决表达二进制的问题。因为,进制越大,数的表达长度也就越短。不过,为什么偏偏是16或8进制,而不其它的诸如7或21进制呢?
2、8、16,分别是2的1次方,3次方,4次方。这一点使得三种进制之间可以非常方便地互相转换。8进制或16进制缩短了二进制数长度,但却保持了二进制数的表达特点。
Q2:怎样区分二进制,八进制,十进制,十六进制?
JAVA中基本类型:
byte:8位,即1字节,表示范围:-128——127
char:16位,即2字节,表示范围:0——65535
short:16位,即2字节,表示范围:-32768——32767
int:32位,即4字节,表示范围:-(2的31次幂)——(2的31次幂)-1
float:32位
long:64位,即8字节,表示范围:-(2的63次幂)——(2的63次幂)-1
double:64位
例如:
二进制(8位机):1000 0000 ——> 十进制:(-128)——>八进制:(0200,虽然0600也表示-128但是9位溢出)——>十六进制:(0x80);
二进制(16位机)1111 1111 1111 1111——>十进制:(-1)——>八进制:(0177777)——>十六进制:(0xFFFF);
二进制(32位机)1111 1111 1111 1111 1111 1111 1111 0001 ——>十进制:(-15)——>八进制:(0377 7777 7761)——>十六进制:(0xFFFF FFF1);
记住一个约定:二进制里是用0和1来表示正负的,最高位为符号位,最高位为1代表负数,最高位为0代表正数;
记住另外一个约定:
八进制:以“0”开头;
十六进制:“0x”开头;
十进制:我们最熟悉,不说了;
二进制:只有0和1的;
但1001100我们怎么看,那要看具体的编程环境的变量或参数类型声明是什么,盲目说是二进制或十进制都是不对的;
EG1:一道典型的JAVA面试题?看看你做得出不O(∩_∩)O~
package org.test;
public class TestJava {
public static void main(String[] args) {
int i = 0xFFFFFFF1;
int j = ~i; // 按位取反运算
System.out.println(i);
System.out.println(j);
}
}
输出结果:
-15
14
这是为什么呢?自己想去O(∩_∩)O~
Q3:八位二进制数为什么表示的范围是: -128 —— +127?
计算机对有符号数(包括浮点数)的表示有三种方法:原码、反码和补码
8位原码能够表示数的范围是 -127~127
8位反码能够表示数的范围是 -127~127
8位补码能够表示数的范围是 -128~127
既然范围是-128~127,那肯定是用补码表示的。
计算机没有你想象的那么聪明,能够自觉的对正数和负数进行区分和识别,所以我们人类就给他们制定了一系列规则:
我们把最高位规定为符号位,1为负,0为正;
1000 0000——1111 1111表示-128到-1, 0000 0000——0111 1111表示0-127;
例如:
已知补码1111 1111——>原码1000 0001,反码1111 1110;
负数补码——>>原码计算规则:
看到最高位为1,一个负数,
把符号位去掉,剩下0111 1111,然后减1得到0111 1110,再取反得到原码1000 0001;
负数补码——>>反码计算规则:
看到最高位为1,一个负数,反码=补码-1,所以得到反码 1111 1110;
若为0表示正数,补码=原码=反码,算都不用算的;
所以说补码就是二进制里表示负数的一种方法,对正数求原码、反码、补码没什么意义;
正数的原码反码补码是一样的.
补码的表示范围为:
(-128~0~127)共256个.
注意: (-128)没有相对应的原码和反码。-128——>(1000 0000)
下面摘抄网上的一些讲解,觉得蛮不错的。
原码:最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
1、原码、反码和补码的表示方法
(1)原码:在数值前直接加一符号位的表示法。
例如: 符号位 数值位
[+7]原= 0 0000111 B
[-7]原= 1 0000111 B
注意:a. 数0的原码有两种形式:
[+0]原=00000000B [-0]原=10000000B
b. 8位二进制原码的表示范围:-127~+127
(2)反码:
正数:正数的反码与原码相同。
负数:负数的反码,符号位为“1”,数值部分按位取反。
例如: 符号位 数值位
[+7]反= 0 0000111 B
[-7]反= 1 1111000 B
注意:a. 数0的反码也有两种形式,即
[+0]反=00000000B
[- 0]反=11111111B
b. 8位二进制反码的表示范围:-127~+127
(3)补码
2)补码的表示:
正数:正数的补码和原码相同。
负数:负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。
例如: 符号位 数值位
[+7]补= 0 0000111 B
[-7]补= 1 1111001 B
补码在微型机中是一种重要的编码形式,请注意:
a.采用补码后,可以方便地将减法运算转化成加法运算,运算过程得到简化。正数的补码即是它所表示的数的真值,而负数的补码的数值部份却不是它所表示的数的真值。采用补码进行运算,所得结果仍为补码。
b.与原码、反码不同,数值0的补码只有一个,即 [0]补=00000000B。
c.若字长为8位,则补码所表示的范围为-128~+127;进行补码运算时,应注意所得结果不应超过补码所能表示数的范围。
2.原码、反码和补码之间的转换
由于正数的原码、补码、反码表示方法均相同,不需转换。
在此,仅以负数情况分析。
(1) 已知原码,求补码。
例:已知某数X的原码为10110100B,试求X的补码和反码。
解:由[X]原=10110100B知,X为负数。求其反码时,符号位不变,数值部分按位求反;求其补码时,再在其反码的末位加1。
1 0 1 1 0 1 0 0 原码
1 1 0 0 1 0 1 1 反码,符号位不变,数值位取反
1 +1
1 1 0 0 1 1 0 0 补码
故:[X]补=11001100B,[X]反=11001011B。
(2) 已知补码,求原码。
分析:按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1 有方法。
例:已知某数X的补码11101110B,试求其原码。
解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。
1 1 1 0 1 1 1 0 补码
1 0 0 1 0 0 0 1 符号位不变,数值位取反
1 +1
1 0 0 1 0 0 1 0 原码
1.3.2 有符号数运算时的溢出问题
请大家来做两个题目:
1)(+72)+(+98)=?
0 1 0 0 1 0 0 0 B +72
+ 0 1 1 0 0 0 1 0 B +98
1 0 1 0 1 0 1 0 B -42
2)(-83)+(-80)=?
1 0 1 0 1 1 0 1 B -83
+ 1 0 1 1 0 0 0 0 B -80
0 1 0 1 1 1 0 1 B +93
思考:这两个题目,按照正常的法则来运算,但结果显然不正确,这是怎么回事呢?
答案:这是因为发生了溢出。
分享到:
相关推荐
Java调用MATLAB,将文件转换为二进制流,http://blog.csdn.net/GSH_Hello_World/article/details/78524897
JAVA读写二进制文件
java随机生成二进制数-java–随机二进制搜索算法 随机搜索算法.pdf
java语言编写的十进制正数和负数转换二进制算法。
刚学Java,老师让座一个实数进制转换的程序,分享出来以供互相学习。
* 压缩图片,将图片压缩后以二进制的形式输出 * * @param file * 将要压缩的图片 * @param width * 压缩宽(长度短的做宽) * @param height * 压缩长(长度长的做长) * @return byte[]二进制流 */
Java把十进制转成二进制(任意进制)的程序
利用Java编写程序,提示用户输入一个十进制整数,然后显示对应的二进制值。在这个程序中不要使用Integer.toBinaryString(int)
本代码信息: 使用语言:java 功能:将整数(包括正负整数)转换成对应的二进制数,然后再控制台上显示。
将文件转为01二进制查看,可修改01二进制再还原成文件
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOperation { public static void...
JAVA二进制流转PDF 1 http接口接收到二进制流,如下,转换成Pdf文件保存到本地 %PDF-1.4 %���� 3 0 obj ...
java 二进制文件的读写操作使用FileInputStream FileOutputStream
java二进制运算器(加、见、乘、除)**********
二进制十进制八进制十六进制转换练习题[借鉴].pdf
读取文件中的二进制文件并将二进制转换成文本文档并输出
java 二进制,位左移,位右移PPT java 二进制,位左移,位右移 java 二进制,位左移,位右移
整数转二进制补码的源代码 提供了两种方法:一种调用java api中的方法。另一种是自己实现的。
任意输入一个十进制整数,包括正数负数,通过程序实现可以输出相应的二进制编码
二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据二进制数据