math类中提供了三个与取整有关的方法:ceil,floor,round,这些方法的作用与它们的英文名称的含义相对应。
例如:
- ceil的英文意义是天花板,该方法就表示向上取整,math.ceil(11.3)的结果为12,math.ceil(-11.6)的结果为-11;
- floor的英文是地板,该方法就表示向下取整,math.floor(11.6)的结果是11,math.floor(-11.4)的结果-12;
- 最难掌握的是round方法,他表示“四舍五入”,算法为math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,math.round(11.5)的结果是12,math.round(-11.5)的结果为-11.
部分源码
public static double ceil(double a) {
return StrictMath.ceil(a); // default impl. delegates to StrictMath
}
public static long round(double a) {
long longBits = Double.doubleToRawLongBits(a);
long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
>> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
+ DoubleConsts.EXP_BIAS) - biasedExp;
if ((shift & -64) == 0) { // shift >= 0 && shift < 64
// a is a finite number such that pow(2,-64) <= ulp(a) < 1
long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
| (DoubleConsts.SIGNIF_BIT_MASK + 1));
if (longBits < 0) {
r = -r;
}
// In the comments below each Java expression evaluates to the value
// the corresponding mathematical expression:
// (r) evaluates to a / ulp(a)
// (r >> shift) evaluates to floor(a * 2)
// ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
// (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
return ((r >> shift) + 1) >> 1;
} else {
// a is either
// - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
// - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
// - an infinity or NaN
return (long) a;
}
}
public static int round(float a) {
int intBits = Float.floatToRawIntBits(a);
int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
>> (FloatConsts.SIGNIFICAND_WIDTH - 1);
int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
+ FloatConsts.EXP_BIAS) - biasedExp;
if ((shift & -32) == 0) { // shift >= 0 && shift < 32
// a is a finite number such that pow(2,-32) <= ulp(a) < 1
int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
| (FloatConsts.SIGNIF_BIT_MASK + 1));
if (intBits < 0) {
r = -r;
}
// In the comments below each Java expression evaluates to the value
// the corresponding mathematical expression:
// (r) evaluates to a / ulp(a)
// (r >> shift) evaluates to floor(a * 2)
// ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
// (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
return ((r >> shift) + 1) >> 1;
} else {
// a is either
// - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
// - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
// - an infinity or NaN
return (int) a;
}
}
public static double floor(double a) {
return StrictMath.floor(a); // default impl. delegates to StrictMath
}
注意
- 可以通过BigDecimal的compareTo方法来进行比较。 返回的结果是int类型,-1表示小于,0是等于,1是大于。
- 下面使用BigDecimal是为了解决Double精度丢失,至于为啥用String类型,因为Double=0.1,传递给构造函数BigDecimal()时可能进度丢失变成0.1999999…
下面写个代码测试一下
// 注意:下面使用BigDecimal是为了解决Double精度丢失,至于为啥用String类型,因为Double=0.1,传递给构造函数BigDecimal()时可能进度丢失变成0.1999999
String startVal = "-2";// 起始值
String endVal = "2";// 结束值
String stepSize = "0.1";// 步长
// ceil 向上取整
System.out.println("ceil 向上取整:");
for (BigDecimal i = new BigDecimal(startVal); i.compareTo(new BigDecimal(endVal)) == -1
|| i.compareTo(new BigDecimal(endVal)) == 0; i = i.add(new BigDecimal(stepSize))) {
System.out.println("Math.ceil(" + i + ") -> " + Math.ceil(i.doubleValue()));
}
// math.round(x)=math.floor(x+0.5) 将原来的数字加上0.5后再向下取整
System.out.println("math.round(x)=math.floor(x+0.5) 将原来的数字加上0.5后再向下取整:");
for (BigDecimal i = new BigDecimal(startVal); i.compareTo(new BigDecimal(endVal)) == -1
|| i.compareTo(new BigDecimal(endVal)) == 0; i = i.add(new BigDecimal(stepSize))) {
System.out.println("Math.round(" + i + ") -> " + Math.round(i.doubleValue()));
}
// floor 向下取整
System.out.println("floor 向下取整:");
for (BigDecimal i = new BigDecimal(startVal); i.compareTo(new BigDecimal(endVal)) == -1
|| i.compareTo(new BigDecimal(endVal)) == 0; i = i.add(new BigDecimal(stepSize))) {
System.out.println("Math.floor(" + i + ") -> " + Math.floor(i.doubleValue()));
}
运行结果
ceil 向上取整:
Math.ceil(-2) -> -2.0
Math.ceil(-1.9) -> -1.0
Math.ceil(-1.8) -> -1.0
Math.ceil(-1.7) -> -1.0
Math.ceil(-1.6) -> -1.0
Math.ceil(-1.5) -> -1.0
Math.ceil(-1.4) -> -1.0
Math.ceil(-1.3) -> -1.0
Math.ceil(-1.2) -> -1.0
Math.ceil(-1.1) -> -1.0
Math.ceil(-1.0) -> -1.0
Math.ceil(-0.9) -> -0.0
Math.ceil(-0.8) -> -0.0
Math.ceil(-0.7) -> -0.0
Math.ceil(-0.6) -> -0.0
Math.ceil(-0.5) -> -0.0
Math.ceil(-0.4) -> -0.0
Math.ceil(-0.3) -> -0.0
Math.ceil(-0.2) -> -0.0
Math.ceil(-0.1) -> -0.0
Math.ceil(0.0) -> 0.0
Math.ceil(0.1) -> 1.0
Math.ceil(0.2) -> 1.0
Math.ceil(0.3) -> 1.0
Math.ceil(0.4) -> 1.0
Math.ceil(0.5) -> 1.0
Math.ceil(0.6) -> 1.0
Math.ceil(0.7) -> 1.0
Math.ceil(0.8) -> 1.0
Math.ceil(0.9) -> 1.0
Math.ceil(1.0) -> 1.0
Math.ceil(1.1) -> 2.0
Math.ceil(1.2) -> 2.0
Math.ceil(1.3) -> 2.0
Math.ceil(1.4) -> 2.0
Math.ceil(1.5) -> 2.0
Math.ceil(1.6) -> 2.0
Math.ceil(1.7) -> 2.0
Math.ceil(1.8) -> 2.0
Math.ceil(1.9) -> 2.0
Math.ceil(2.0) -> 2.0
math.round(x)=math.floor(x+0.5) 将原来的数字加上0.5后再向下取整:
Math.round(-2) -> -2
Math.round(-1.9) -> -2
Math.round(-1.8) -> -2
Math.round(-1.7) -> -2
Math.round(-1.6) -> -2
Math.round(-1.5) -> -1
Math.round(-1.4) -> -1
Math.round(-1.3) -> -1
Math.round(-1.2) -> -1
Math.round(-1.1) -> -1
Math.round(-1.0) -> -1
Math.round(-0.9) -> -1
Math.round(-0.8) -> -1
Math.round(-0.7) -> -1
Math.round(-0.6) -> -1
Math.round(-0.5) -> 0
Math.round(-0.4) -> 0
Math.round(-0.3) -> 0
Math.round(-0.2) -> 0
Math.round(-0.1) -> 0
Math.round(0.0) -> 0
Math.round(0.1) -> 0
Math.round(0.2) -> 0
Math.round(0.3) -> 0
Math.round(0.4) -> 0
Math.round(0.5) -> 1
Math.round(0.6) -> 1
Math.round(0.7) -> 1
Math.round(0.8) -> 1
Math.round(0.9) -> 1
Math.round(1.0) -> 1
Math.round(1.1) -> 1
Math.round(1.2) -> 1
Math.round(1.3) -> 1
Math.round(1.4) -> 1
Math.round(1.5) -> 2
Math.round(1.6) -> 2
Math.round(1.7) -> 2
Math.round(1.8) -> 2
Math.round(1.9) -> 2
Math.round(2.0) -> 2
floor 向下取整:
Math.floor(-2) -> -2.0
Math.floor(-1.9) -> -2.0
Math.floor(-1.8) -> -2.0
Math.floor(-1.7) -> -2.0
Math.floor(-1.6) -> -2.0
Math.floor(-1.5) -> -2.0
Math.floor(-1.4) -> -2.0
Math.floor(-1.3) -> -2.0
Math.floor(-1.2) -> -2.0
Math.floor(-1.1) -> -2.0
Math.floor(-1.0) -> -1.0
Math.floor(-0.9) -> -1.0
Math.floor(-0.8) -> -1.0
Math.floor(-0.7) -> -1.0
Math.floor(-0.6) -> -1.0
Math.floor(-0.5) -> -1.0
Math.floor(-0.4) -> -1.0
Math.floor(-0.3) -> -1.0
Math.floor(-0.2) -> -1.0
Math.floor(-0.1) -> -1.0
Math.floor(0.0) -> 0.0
Math.floor(0.1) -> 0.0
Math.floor(0.2) -> 0.0
Math.floor(0.3) -> 0.0
Math.floor(0.4) -> 0.0
Math.floor(0.5) -> 0.0
Math.floor(0.6) -> 0.0
Math.floor(0.7) -> 0.0
Math.floor(0.8) -> 0.0
Math.floor(0.9) -> 0.0
Math.floor(1.0) -> 1.0
Math.floor(1.1) -> 1.0
Math.floor(1.2) -> 1.0
Math.floor(1.3) -> 1.0
Math.floor(1.4) -> 1.0
Math.floor(1.5) -> 1.0
Math.floor(1.6) -> 1.0
Math.floor(1.7) -> 1.0
Math.floor(1.8) -> 1.0
Math.floor(1.9) -> 1.0
Math.floor(2.0) -> 2.0