深入学习java源码之Math.nextAfter()与 Math.nextUp()
java中的前加加++和后加加++
前++是先自加再使用而后++是先使用再自加!
a = b++; // ++写在后面,说明前面那个东西前用了,也就是b先赋值给a了,然后b再+1
a = ++b; // ++写在前面,说明++先有效,即b要+1,然后赋值给a
最终效果上是a的值不同,而b的值都做了+1操作,只是先赋值还是先+1的问题。
h = h++;
System.out.println("h = " + h);
h = ++h;
System.out.println("h = " + h);
h = 3
h = 4
对于我们常写的for (int i = 0; i < n; i++) {} 这个++写前写后都一样,实际上我们在这里需要的是先+1,再参与后续的操作,但写成++1就有些别扭,至少SUN的源文件中for循环中都是写i++的。
也就是说,++在前在后的影响,只在一条语句中有效,即一个分号“;”中有效。出了这个分号就不好用了。所以for循环的i++怎么写都行,因为这个分号不涉及其它操作,也就无所谓先后了。
java中复合赋值运算符
复合赋值运算符,也称为赋值缩写,带有运算的赋值运算符。共有10种这样的运算符,它们是:+= 加赋值,-= 减赋值,*= 乘赋值,/= 除赋值,%= 求余赋值,&= 按位与赋值,| = 按位或赋值,^= 按位异或赋值,= 右移位赋值。
复合赋值运算举例:
x*=y 即为x=x*y
a+=2 即为a=a+2
执行一次a=a+2,就等于给a重新赋了值,这个值就是a+1
真正意义包含两个部分,一是“+”,就是通常所说的直接相加,二是改变结果的类型:将计算结果的类型转换为“+=”符号左边的对象的类型。
x+=1一般在循环下使用,能发挥它的最大的作用。 例如:
while(true){
if(x>10)break;
x+=1;}
Modifier and TypeMethod and Description
static double
nextAfter(double start, double direction)
返回与第二个参数方向相邻的第一个参数的浮点数。
static float
nextAfter(float start, double direction)
返回与第二个参数方向相邻的第一个参数的浮点数。
static double
nextDown(double d)
返回与负无穷大方向相邻的 d
的浮点值。
static float
nextDown(float f)
返回与负无穷大方向相邻的 f
的浮点值。
static double
nextUp(double d)
返回与正无穷大方向相邻的 d
的浮点值。
static float
nextUp(float f)
返回与正无穷大方向相邻的 f
的浮点值。
java源码
public final class Math {
private Math() {}
public static double nextAfter(double start, double direction) {
/*
* The cases:
*
* nextAfter(+infinity, 0) == MAX_VALUE
* nextAfter(+infinity, +infinity) == +infinity
* nextAfter(-infinity, 0) == -MAX_VALUE
* nextAfter(-infinity, -infinity) == -infinity
*
* are naturally handled without any additional testing
*/
// First check for NaN values
if (Double.isNaN(start) || Double.isNaN(direction)) {
// return a NaN derived from the input NaN(s)
return start + direction;
} else if (start == direction) {
return direction;
} else { // start > direction or start < direction
// Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
// then bitwise convert start to integer.
long transducer = Double.doubleToRawLongBits(start + 0.0d);
/*
* IEEE 754 floating-point numbers are lexicographically
* ordered if treated as signed- magnitude integers .
* Since Java's integers are two's complement,
* incrementing" the two's complement representation of a
* logically negative floating-point value *decrements*
* the signed-magnitude representation. Therefore, when
* the integer representation of a floating-point values
* is less than zero, the adjustment to the representation
* is in the opposite direction than would be expected at
* first .
*/
if (direction > start) { // Calculate next greater value
transducer = transducer + (transducer >= 0L ? 1L:-1L);
} else { // Calculate next lesser value
assert direction < start;
if (transducer > 0L)
--transducer;
else
if (transducer < 0L )
++transducer;
/*
* transducer==0, the result is -MIN_VALUE
*
* The transition from zero (implicitly
* positive) to the smallest negative
* signed magnitude value must be done
* explicitly.
*/
else
transducer = DoubleConsts.SIGN_BIT_MASK | 1L;
}
return Double.longBitsToDouble(transducer);
}
}
public static float nextAfter(float start, double direction) {
/*
* The cases:
*
* nextAfter(+infinity, 0) == MAX_VALUE
* nextAfter(+infinity, +infinity) == +infinity
* nextAfter(-infinity, 0) == -MAX_VALUE
* nextAfter(-infinity, -infinity) == -infinity
*
* are naturally handled without any additional testing
*/
// First check for NaN values
if (Float.isNaN(start) || Double.isNaN(direction)) {
// return a NaN derived from the input NaN(s)
return start + (float)direction;
} else if (start == direction) {
return (float)direction;
} else { // start > direction or start < direction
// Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
// then bitwise convert start to integer.
int transducer = Float.floatToRawIntBits(start + 0.0f);
/*
* IEEE 754 floating-point numbers are lexicographically
* ordered if treated as signed- magnitude integers .
* Since Java's integers are two's complement,
* incrementing" the two's complement representation of a
* logically negative floating-point value *decrements*
* the signed-magnitude representation. Therefore, when
* the integer representation of a floating-point values
* is less than zero, the adjustment to the representation
* is in the opposite direction than would be expected at
* first.
*/
if (direction > start) {// Calculate next greater value
transducer = transducer + (transducer >= 0 ? 1:-1);
} else { // Calculate next lesser value
assert direction < start;
if (transducer > 0)
--transducer;
else
if (transducer < 0 )
++transducer;
/*
* transducer==0, the result is -MIN_VALUE
*
* The transition from zero (implicitly
* positive) to the smallest negative
* signed magnitude value must be done
* explicitly.
*/
else
transducer = FloatConsts.SIGN_BIT_MASK | 1;
}
return Float.intBitsToFloat(transducer);
}
}
public static double nextUp(double d) {
if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
return d;
else {
d += 0.0d;
return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
((d >= 0.0d)?+1L:-1L));
}
}
public static float nextUp(float f) {
if( Float.isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)
return f;
else {
f += 0.0f;
return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
((f >= 0.0f)?+1:-1));
}
}
public static double nextDown(double d) {
if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
return d;
else {
if (d == 0.0)
return -Double.MIN_VALUE;
else
return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
((d > 0.0d)?-1L:+1L));
}
}
public static float nextDown(float f) {
if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
return f;
else {
if (f == 0.0f)
return -Float.MIN_VALUE;
else
return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
((f > 0.0f)?-1:+1));
}
}
}
public final class StrictMath {
private StrictMath() {}
public static double nextAfter(double start, double direction) {
return Math.nextAfter(start, direction);
}
public static float nextAfter(float start, double direction) {
return Math.nextAfter(start, direction);
}
public static double nextUp(double d) {
return Math.nextUp(d);
}
public static float nextUp(float f) {
return Math.nextUp(f);
}
public static double nextDown(double d) {
return Math.nextDown(d);
}
public static float nextDown(float f) {
return Math.nextDown(f);
}
}