/* |
* Copyright reserved 2010 by AllensLab |
* @project AllensLab |
* @date Feb 22, 2010 |
*/ |
package cn.allen.tools; |
|
import java.math.BigDecimal; |
|
/** |
* RoundTool |
* @author allen |
* @time 10:05:40 AM Feb 22, 2010 |
*/ |
public class RoundTools { |
/** |
* 对double数据进行取精度. |
* <p> |
* For example: <br> |
* double value = 100.345678; <br> |
* double ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br> |
* ret为100.3457 <br> |
* |
* @param value |
* double数据. |
* @param scale |
* 精度位数(保留的小数位数). |
* @param roundingMode |
* 精度取值方式. |
* @return 精度计算后的数据. |
*/ |
public static double round(double value, int scale, int roundingMode) { |
BigDecimal bd = new BigDecimal(value); |
bd = bd.setScale(scale, roundingMode); |
double d = bd.doubleValue(); |
bd = null; |
return d; |
} |
|
public static BigDecimal roundAgain(double value, int scale, int roundingMode) { |
BigDecimal bd = new BigDecimal(value); |
bd = bd.setScale(scale, roundingMode); |
return bd; |
} |
|
/* 用于加、减、乘和除的方法给 BigDecimal 值提供了算术运算。由于 BigDecimal 对象是不可变的,这些方法中的每一个都会产生新的 BigDecimal 对象。 |
* 因为创建对象的开销, BigDecimal 不适合于大量的数学计算,但设计它的目的是用来精确地表示小数。 */ |
|
/** |
* Addition |
* @param number1 |
* @param number2 |
* @return |
* @author allen |
* @date 10:42:47 AM Feb 22, 2010 |
*/ |
public static double add(double number1, double number2, int newScale, int roundingMode) { |
return BigDecimal.valueOf(number1).add(BigDecimal.valueOf(number2)).setScale(newScale, roundingMode).doubleValue(); |
} |
|
public static double add(int newScale, int roundingMode, double number1, double numbers) { |
BigDecimal bd = new BigDecimal(number1); |
for (double number : numbers) { |
bd = bd.add(BigDecimal.valueOf(number).setScale(newScale, roundingMode)); |
} |
return bd.doubleValue(); |
} |
|
/** |
* Subtraction |
* @param number1 |
* @param number2 |
* @return |
* @author allen |
* @date 10:45:36 AM Feb 22, 2010 |
*/ |
public static double subtract(double number1, double number2, int newScale, int roundingMode) { |
return BigDecimal.valueOf(number1).subtract(BigDecimal.valueOf(number2)).setScale(newScale, roundingMode).doubleValue(); |
} |
|
/** |
* Multiplication |
* @param number1 |
* @param number2 |
* @return |
* @author allen |
* @date 10:46:23 AM Feb 22, 2010 |
*/ |
public static double multiply(double number1, double number2, int newScale, int roundingMode) { |
return BigDecimal.valueOf(number1).multiply(BigDecimal.valueOf(number2)).setScale(newScale, roundingMode).doubleValue(); |
|
} |
|
/** |
* Division |
* 尽量采用财务常用的四舍六入五取偶 即ROUND_HALF_EVEN |
* @param number1 |
* @param number2 |
* @return |
* @author allen |
* @date 10:47:12 AM Feb 22, 2010 |
*/ |
public static double divide(double number1, double number2, int scale, int roundingMode) { |
return BigDecimal.valueOf(number1).divide(BigDecimal.valueOf(number2), scale, roundingMode).doubleValue(); |
} |
|
/** |
* 测试用的main方法. |
* |
* @param args |
* 运行参数. |
*/ |
public static void main(String[] args) { |
//下面都以保留2位小数为例 |
System.out.println(add(12.341, 12.3449, 2, BigDecimal.ROUND_HALF_EVEN)); |
System.out.println(add(2, BigDecimal.ROUND_HALF_UP, 12.346, 12.3449, 12.3401, 12.345)); |
System.out.println(subtract(12.3449, 12.341, 2, BigDecimal.ROUND_HALF_EVEN)); |
System.out.println(multiply(12.3449, 0.01, 2, BigDecimal.ROUND_HALF_UP)); |
System.out.println(divide(11.341, 12.346, 2, BigDecimal.ROUND_HALF_EVEN)); |
//ROUND_UP |
//只要第2位后面存在大于0的小数,则第2位就+1 |
System.out.println("-- ROUND_UP -- 只要第2位后面存在大于0的小数,则第2位就+1 --"); |
System.out.println(round(12.3401, 2, BigDecimal.ROUND_UP));//12.35 |
System.out.println(round(-12.3401, 2, BigDecimal.ROUND_UP));//-12.35 |
//ROUND_DOWN |
//与ROUND_UP相反 |
//直接舍弃第2位后面的所有小数 |
System.out.println("-- ROUND_DOWN -- 直接舍弃第2位后面的所有小数 --"); |
System.out.println(round(12.349, 2, BigDecimal.ROUND_DOWN));//12.34 |
System.out.println(round(-12.349, 2, BigDecimal.ROUND_DOWN));//-12.34 |
//ROUND_CEILING |
//如果数字>0 则和ROUND_UP作用一样 |
//如果数字<0 则和ROUND_DOWN作用一样 |
System.out.println("-- OUND_CEILING -- 如果数字>0 则和ROUND_UP作用一样 如果数字<0 则和ROUND_DOWN作用一样 --"); |
System.out.println(round(12.3401, 2, BigDecimal.ROUND_CEILING));//12.35 |
System.out.println(round(-12.349, 2, BigDecimal.ROUND_CEILING));//-12.34 |
//ROUND_FLOOR |
//如果数字>0 则和ROUND_DOWN作用一样 |
//如果数字<0 则和ROUND_UP作用一样 |
System.out.println("-- ROUND_FLOOR -- 如果数字>0 则和ROUND_DOWN作用一样 如果数字<0 则和ROUND_UP作用一样 --"); |
System.out.println(round(12.349, 2, BigDecimal.ROUND_FLOOR));//12.34 |
System.out.println(round(-12.3401, 2, BigDecimal.ROUND_FLOOR));//-12.35 |
//ROUND_HALF_UP [这种方法最常用] |
//如果第3位数字>=5,则第2位数字+1 |
//备注:只看第3位数字的值,不会考虑第3位之后的小数的 |
System.out.println("-- ROUND_HALF_UP -- 如果第3位数字>=5,则第2位数字+1 --"); |
System.out.println(round(12.345, 2, BigDecimal.ROUND_HALF_UP));//12.35 |
System.out.println(round(12.3449, 2, BigDecimal.ROUND_HALF_UP));//12.34 |
System.out.println(round(-12.345, 2, BigDecimal.ROUND_HALF_UP));//-12.35 |
System.out.println(round(-12.3449, 2, BigDecimal.ROUND_HALF_UP));//-12.34 |
//ROUND_HALF_DOWN |
//如果第3位数字>=5,则做ROUND_UP |
//如果第3位数字<5,则做ROUND_DOWN |
System.out.println("-- ROUND_HALF_DOWN -- 如果第3位数字>=5,则做ROUND_UP,如果第3位数字<5,则做ROUND_DOWN --"); |
System.out.println(round(12.345, 2, BigDecimal.ROUND_HALF_DOWN));//12.35 |
System.out.println(round(12.3449, 2, BigDecimal.ROUND_HALF_DOWN));//12.34 |
System.out.println(round(-12.345, 2, BigDecimal.ROUND_HALF_DOWN));//-12.35 |
System.out.println(round(-12.3449, 2, BigDecimal.ROUND_HALF_DOWN));//-12.34 |
//ROUND_HALF_EVEN |
//如果第3位是偶数,则做ROUND_HALF_DOWN |
//如果第3位是奇数,则做ROUND_HALF_UP |
System.out.println("-- ROUND_HALF_EVEN -- 如果第3位是偶数,则做ROUND_HALF_DOWN,如果第3位是奇数, 则做ROUND_HALF_UP --"); |
System.out.println(round(12.346, 2, BigDecimal.ROUND_HALF_EVEN));//12.35 |
System.out.println(round(12.345, 2, BigDecimal.ROUND_HALF_EVEN));//12.35 |
} |
} |
|