JVM的概念
略过
JVM发展历史
略过
JVM种类
略过
Java语言规范
主要定义语法、变量、类型、文法之类的信息
略过
JVM规范
主要定义Class文件类型、运行时数据、祯栈、虚拟机的启动、虚拟机的指令集之类的信息
Java语言和JVM相对独立(以下语言皆使用JVM,符合JVM规范)
- Groovy
- Clojure
- Scala
1. 整数的表达()
- 原码:第一位为符号位(0为正数,1为负数)
- 反码:符号位不动,原码取反
- 负数补码:符号位不动,反码加1
-6
原码: 10000110
反码: 11111001
补码: 11111010
-1
原码: 10000001
反码: 11111110
补码: 11111111
- 正数补码:和原码相同
5
00000101
- 打印整数的二进制表示
int a=-6;
for(int i=0;i<32;i++){
int t=(a & 0x80000000>>>i)>>>(31-i);
System.out.print(t);
}
2. 为什么要用补码?
- 没有歧义的表示0(无论看作正数还是负数)
0
正数:00000000
负数:10000000
反码:11111111
补码:00000000
- 源码计算难以得到期望的结果;补码计算、符号位参与运算就能得到正确的结果
-6+5 -4+5
11111010 11111100
+ 00000101 + 00000101
= 11111111 = 00000001
3. float的表示与定义
详见此文件夹下的文件:float的表示
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
指数:8 尾数:23
e全0 尾数附加位为0 否则尾数附加位为1
s * m * 2^(e-127)
作业
- 有关补码,简要阐述补码的好处。并计算给出 -99, -105, 205 整数的补码
答:a. 可以无歧义的表示0;
0为正数
原码、补码 00000000
0为负数
原码 10000000
反码 11111111
补码 00000000
b. 使用原码计算可能得不到想要的结果,而使用补码,符号位参与运算能得到准确的结果。
-99 -105 205
原码 1110,0011 原码 1110,1001 0000,0000,1100,1101
反码 1001,1100 反码 1001,0110
补码 1001,1101 补码 1001,0111
- 有关浮点数,根据IEEE745,计算1,10000010,00100000000000000000000的单精度浮点的值,并给出计算过程。
答:公式为 s * m * 2^(e-127)
e=1000,0010=2^1+2^7=130
m=1+2^-3=1.125
v=-2^(130-127) * 1.125=-9
3.写一个Java程序,将100.2转成IEEE745 二进制表示 ,给出程序和结果。
/**
* 将输入的double转成IEEE745二进制表示
* @param d 要转换的浮点数
*/
public static void printDouble(double d){
//最终要输出的值
StringBuilder dStr = new StringBuilder();
/* 1. 将浮点数d的整数和小数分别表示成二进制形式 */
int integer = (int) d; //整数值
double decimals = d - integer; //小数值
System.out.println("小数值为: " + decimals);
//整数值的二进制表示
String integerStr = Integer.toBinaryString(integer);
//小数值的二进制表示
StringBuilder decimalStr = new StringBuilder();
int count = 32; //小数取位数32位
for (int i = 0; i < count; i++) {
decimals = decimals * 2;
if(decimals > 1){ //整数部分取1
decimalStr.append(1);
decimals -= 1;
}else{ //整数部分取0
decimalStr.append(0);
}
}
System.out.println("整数部分的二进制为: " + integerStr);
System.out.println("小数部分的二进制为: " + decimalStr);
/* 2. 填充符号位 */
dStr.append(d > 0?0:1);
/* 3. 左移或者右移小数点到第一个有效数字 */
/* 4. 小数点移位数加127后取二进制填充到e值 */
if(integer > 0){ //取有效数字,小数点左移
//根据整数二进制字符串长度来确定左移位数
int bit = integerStr.length() -1;
dStr.append(Integer.toBinaryString(bit + 127)); //填充e值
decimalStr.insert(0, integerStr.substring(1)); //将整数部分移位后的值插入到小数部分前面
}else{ //取有效数字,小数点右移
//暂时不需要实现
}
// 5. 小数点后取23位填充到m值
dStr.append(decimalStr.subSequence(0, 23)); //填充m值
System.out.println("100.2的IEEE745二进制表示为: " + dStr);
}
输出结果为:
整数部分的二进制为: 1100100
小数部分的二进制为: 00110011001100110011001100110011
100.2的IEEE745二进制表示为: 01000010110010000110011001100110