第一题:奇数性
isOdd方法用来确定传来的参数是否是奇数,由于当传入负数i时,i%2的值为-1或0,负奇数也不能判断正确。由于偶数是对2取余为0,所以应该将i%2==1修改为i%2!=0。修改后,奇数对2取余不是正1或负1都能满足。
public static boolean isOdd(int i) {
return i%2==1;
}
第二题:找零时刻
public static void main(String[] args) {
double result= 2.00 - 1.10;
System.out.println(result);
System.out.println("2.00双精度在内存表示(16进制):"+ChapterUtil.getIEE754FromDouble(2.00));
System.out.println("1.10双精度在内存表示(16进制):"+ChapterUtil.getIEE754FromDouble(1.10));
System.out.println("2.00-1.10结果双精度在内存表示(16进制):"+ChapterUtil.getIEE754FromDouble(result));
System.out.println("0.90双精度在内存表示(16进制):"+ChapterUtil.getIEE754FromDouble(0.9));
}
//控制台输出:
//0.8999999999999999
//2.00双精度在内存表示(16进制):4000000000000000
//1.10双精度在内存表示(16进制):3ff199999999999a
//2.00-1.10结果双精度在内存表示(16进制):3feccccccccccccc
//0.90双精度在内存表示(16进制):3feccccccccccccd
ChapterUtils是一个查看数字在内存存储的工具类
public class ChapterUtil {
public static String getIEE754FromFloat(float i) {
return Integer.toHexString(Float.floatToRawIntBits(i));
}
public static String getFromInt(int i) {
return Integer.toHexString(i);
}
public static String getFromLong(long i) {
return Long.toHexString(i);
}
public static String getIEE754FromDouble(double i) {
return Long.toHexString(Double.doubleToRawLongBits(i));
}
}
2.0-1.1 涉及浮点数加减法
在我的一篇博客中介绍了float在内存存储方式,其实double也差不多
double 符号位1位,指数位11位,尾数52位
2.0是正数,符号位0,2的二进制表示为 1∗21 1 ∗ 2 1 ,指数是1,所以指数位为1+1023= 1024(10)=400(16) 1024 ( 10 ) = 400 ( 16 ) ,所以符号位包括指数位就是 400(16) 400 ( 16 ) ,其余由于指数位不全为0,所以是规格的,尾数省去1,都是0.
1.1是正数,符号位0, 1.1的二进制表示为 1.000110011⋯以0011循环∗20 1.000110011 ⋯ ⏟ 以 0011 循 环 ∗ 2 0 ,由于double尾数只能存52位,所以尾数就是 1⋯11个9a(16) 1 ⋯ ⏟ 11 个 9 a ( 16 ) ,最后一位为a,是因为最后一个9后面还是1,所以进一位由9变为a。指数为0,指数位就是0+1023= 1023(10)=3ff(16) 1023 ( 10 ) = 3 f f ( 16 ) .
浮点数的减法,先对阶,1.1的指数也就是阶码比2少1,尾数向右移一位,隐藏的那一位也右移,得到 8⋯11个cd(16) 8 ⋯ ⏟ 11 个 c d ( 16 ) ,然后计算尾数的减法,得到 7⋯12个3 7 ⋯ ⏟ 12 个 3 ,进行规范化操作,因为不满足规范化,向左移2位,最后补0,阶码减2,最后尾数为 ⋯13个c ⋯ ⏟ 13 个 c ,指数位为-1,所以指数位和符号位一起就是 3fe(16) 3 f e ( 16 ) .最终结果为 3fe⋯13个c 3 f e ⋯ ⏟ 13 个 c .
第三题:长整除
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
final long MICROS_PER_DAY_LATER = 24L * 60 * 60 * 1000 * 1000;
System.out.println("一天中微秒数:溢出后的数"+MICROS_PER_DAY);
System.out.println("一天中微秒数:正确的值"+MICROS_PER_DAY_LATER);
System.out.println("正确的long在内存存储为:"+ChapterUtil.getFromLong(MICROS_PER_DAY_LATER));
System.out.println("溢出后的值在内存存储为:"+ChapterUtil.getFromLong(MICROS_PER_DAY));
System.out.println(MILLIS_PER_DAY);
System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);
}
//控制台输出:
//一天中微秒数:溢出后的数500654080
//一天中微秒数:正确的值86400000000
//正确的long在内存存储为:141dd76000
//溢出后的值在内存存储为:1dd76000
//86400000
//5
由于int与int相乘只会保存在int里,由于最终的结果已经超出int的范围,即使保存在long里,也只是溢出后的值。因为由内存存储可见,舍去了8位,14是十六进制的。
第四题:初级问题
public static void main(String[] args) {
System.out.println(12345+5432l);
}
//控制台打印:
//17777
由于5432l中l很像1,特别容易看错,所以一定要用大写的L来表示一个长整数。