Thinking in Java 笔记:Operators

数学没学好,补充点数学知识
e:欧拉数,自然对数函数的底数.
(1+1/n)的n次方,n趋于无穷大,所得到的数就是e.
e不论对x微分几次,结果都还是e.导致一些无聊的数学系学生用e比喻坚定不移的爱情.

ln以e为底数,lg以10为底数.

在Java中,e以Math.E存在
由于FORTRAN最初是一个UPPERCASE Language,在FORTRAN中E作为Exponential的简写代表以10为基数的幂来用,而不会和e混淆,然后C,C++,Java也都这么干了,所以:
像 1.39e-43f 这样的东西表示 1.39*10^-43 而不是 1.39*e^-43

编译器默认将指数作为双精度数(double)处理,所以
float f4 = 1.39e-43 包含了一个窄化转换的操作,编译报错
float f4 = 1.39e-43f 指出右边是一个float常量,编译通过

截断与舍入:当从float或double向int转型时,小数点后边的数值被截断并直接丢弃而不会进行四舍五入的操作,若需要四舍五入的操作,可用Marh.round()方法.

提升(Promotion):通常,表达式中出现的最大数据类型决定了表达式最终结果的数据类型.比int小的数据类型(short,byte,char)执行算术运算或按位运算前会自动转换成int类型,最终生成的结果也是int类型,如果要把结果赋给较小的数据类型,就需要使用强制类型转换,并可能出现信息丢失.

逻辑运算符 VS 按位运算符
1.逻辑运算符只能操作布尔值或者一个能产生布尔值的表达式;按位运算符能操作整型值,包括byte、short、int、long,但是不能操作浮点型值(即float和double),它还可以操作字符型(char)值。
2.逻辑运算符的运算遵循短路形式,而按位运算符则不是。

移位运算符
移位运算符和按位运算符一样,同属于位运算符,因此移位运算符的位指的也是二进制位。它包括以下几种:

[list=1]
[*]左移位(<<):将操作符左侧的操作数向左移动操作符右侧指定的位数。移动的规则是在二进制的低位补0。
[*]有符号右移位(>>):将操作符左侧的操作数向右移动操作符右侧指定的位数。移动的规则是,如果被操作数的符号为正,则在二进制的高位补0;如果被操作数的符号为负,则在二进制的高位补1。
[*]无符号右移位(>>>):将操作符左侧的操作数向右移动操作符右侧指定的位数。移动的规则是,无论被操作数的符号是正是负,都在二进制位的高位补0。
[*]byte、short、char在做移位运算之前,会被自动转换为int类型,然后再进行运算。
[*]byte、short、int、char类型的数据经过移位运算后结果都为int型。
[*]long经过移位运算后结果为long型。
[*]在移位运算时,如果要操作数大于被操作数对应数据类型所能表示的最大位数,那么先将操作数对该类型所能表示的最大位数(short,,char,byte为32,long为64)求余后,再将被被操作数移位所得余数对应的数值。比如1<<35=1<<(35%32)=1<<3=8。
[/list]

补充:java中数值编码为补码形式.
正数的原码,补码相同;
负数的补码:符号位不变,其余位根据其绝对值的原码逐位取反,并在最低一位加一求得.

移位可与等号(<<=,>>=,>>>=)组合使用.
如果对byte或short进行无符号右移结合赋值操作时,它们会先被转成int,然后被截断并赋予原来的值,可能产生不正确的结果.

移位操作会改变符号位的值,移出存储范围的值被丢弃而不是回放回队尾(C中好象有这种移位方法)
如下代码所示

public abstract class Test2 {
public static void main(String[] args) {
System.out.println("-7的补码"+Integer.toBinaryString(-7));
System.out.println("-7>>2 = "+Integer.toBinaryString(-7>>2));
System.out.println("-7>>>2 = "+Integer.toBinaryString(-7>>>2));
System.out.println("7<<28= " + (7<<28) +" BinaryString = " +Integer.toBinaryString(7<<28));
System.out.println("7<<29= " + (7<<29) + "BinaryString =" + Integer.toBinaryString(7<<29));
System.out.println("7<<30= " + (7<<30) +"BinaryString ="+ Integer.toBinaryString(7<<30));
System.out.println("1 << 31 = " + (1 << 31));
System.out.println("-1 << 31 = " + (-1 << 31));
int h = 65536*65536/2;
int j = 65536/2*65536;
int k = -65536/2*65536;
System.out.println("65536*65536/2=" + Integer.toBinaryString(h));
System.out.println("65536/2*65536="+ Integer.toBinaryString(j));
System.out.println("-65536/2*65536=" + Integer.toBinaryString(k));

}
} //output:
//-7的补码11111111111111111111111111111001
//-7>>2 = 11111111111111111111111111111110 有符号右移位
//-7>>>2 = 111111111111111111111111111110 无符号右移位,
// 实际上是00111111111111111111111111111110
//7<<28= 1879048192 BinaryString = 1110000000000000000000000000000
// 实际上是01110000000000000000000000000000
//7<<29= -536870912BinaryString =11100000000000000000000000000000 符号位被改写
//7<<30= -1073741824BinaryString =11000000000000000000000000000000
//1 << 31 = -2147483648 最小int值-2^31 最高位的1被丢弃
//-1 << 31 = -2147483648
//65536*65536/2=0 溢出
//65536/2*65536=10000000000000000000000000000000 -2^31的补码表示
//-65536/2*65536=10000000000000000000000000000000



参考文章: 臧圩人:JAVA面试题解惑系列 (11)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值