深入學習java原始碼之Math.nextAfter()與 Math.nextUp()
阿新 • • 發佈:2019-01-05
深入學習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 Type | Method and Description |
---|---|
static double |
nextAfter(double start, double direction) 返回與第二個引數方向相鄰的第一個引數的浮點數。 |
static float |
nextAfter(float start, double direction) 返回與第二個引數方向相鄰的第一個引數的浮點數。 |
static double |
nextDown(double d) 返回與負無窮大方向相鄰的 |
static float |
nextDown(float f) 返回與負無窮大方向相鄰的 |
static double |
nextUp(double d) 返回與正無窮大方向相鄰的 |
static float |
nextUp(float 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);
}
}