java四舍五入,
java四舍五入,
java中Math类中提供了三个与取整有关的方法:
分别是ceil、floor、round,这些方法的作用与它们的英文名称的含义相对应
ceil的英文解释是天花板,该方法就表示向上取整,所以,Math.ceil(16.2)的结果为16,Math.ceil(-16.2)的结果是-16;
floor的英文解释是地板,所以该方法就表示向下取整,那么Math.floor(16.6)的结果为16,Math.floor(-16.6)的结果是-17;
round方法比前两个稍微复杂一点,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(16.2)的结果为17,Math.round(-16.2)的结果为-16.
BigDecimal类
BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以
10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue × 10-scale)。
3.1构造函数(主要测试参数类型为double和String的两个常用构造函数)
BigDecimal(double val)
BigDecimal(int val)
BigDecimal(long val)
BigDecimal(Stringval)
BigDecimal aDouble =new BigDecimal(1.22);
System.out.println("construct with a double value: " + aDouble);
BigDecimal aString =new BigDecimal("1.22");
System.out.println("construct with a String value: " + aString);
你认为输出结果会是什么呢?如果你没有认为第一个会输出1.22,那么恭喜你答对了,输出结果如下:
construct with a doublevalue:1.2199999999999999733546474089962430298328399658203125
construct with a String value: 1.22
JDK的描述:1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法。
3、当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)
方法,然后使用BigDecimal(String)
构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)
方法。
精度和舍入
setScale(int newScale)
setScale(int newScale, int roundingMode)
setScale(int newScale, RoundingMode roundingMode)
newScale:小数位数
roundingMode: 舍入方法
setScale(int newScale):此方法使用时容易抛出异常,因为没有定义如何舍入方式。
舍入方式:
ROUND_CEILING:向数轴正方向舍入
0.333 -> 0.34
-0.333 -> -0.33
ROUND_DOWN:向0舍入
0.333 -> 0.33
-0.333 -> -0.33
ROUND_FLOOR:向数轴正负方向舍入
0.333 -> 0.33
-0.333 -> -0.34
ROUND_HALF_UP: >= 0.5进一
0.5 -> 1.0
0.4 -> 0.0
ROUND_HALF_DOWN:> 0.5进一
0.5 -> 0.0
0.6 -> 1.0
ROUND_HALF_EVEN:如果进位的左边为偶数则舍,奇数则入
a = new BigDecimal("2.5"); //5左边的数是偶数,所以舍
b = new BigDecimal("1.5"); //左边的数是奇数,所以舍
a.setScale(0, BigDecimal.ROUND_HALF_EVEN).toString() // => 2
b.setScale(0, BigDecimal.ROUND_HALF_EVEN).toString() // => 2
保留位
方法一:四舍五入,因为获得是double,所以只能是1.0而不能是1.00
[java] view plain copy
- double f = 111231.5585;
- BigDecimal b = new BigDecimal(f);
- double f1 = b.setScale(2, RoundingMode.HALF_UP).doubleValue();
在这里使用BigDecimal ,并且采用setScale方法来设置精确度,同时使用RoundingMode.HALF_UP表示使用最近数字舍入法则来近似计算。在这里我们可以看出BigDecimal和四舍五入是绝妙的搭配。
可以:结合方法二获得准确的String值。
float expectDistanceItem = new BigDecimal(kmDistanceItem).divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP).floatValue();
DecimalFormat df = new DecimalFormat("#0.00");
df.format(expectDistanceItem)
方式二:因为获得是String,所以保留两位小数的话,可以是1.00
[java] view plain copy
- java.text.DecimalFormat df =new java.text.DecimalFormat("#.00");
- df.format(你要格式化的数字);
0 表示不管该位置存不存在字符都显示,不存在的字符用0代替
#表示如果该位存在字符,则显示字符,如果不存在,则不显示 .
小数的分隔符的占位符
因为这个原因:构造方法出现0#.##,##.#0,会报错,即以小数点为分界点,整数#的前面不能有0,小数#的后面不能有0,
例子:
DecimalFormat df1 = new DecimalFormat("0.0");
DecimalFormat df2 = new DecimalFormat("#.#");
DecimalFormat df3 = new DecimalFormat("000.000");
DecimalFormat df4 = new DecimalFormat("###.###");
System.out.println(df1.format(12.34));
System.out.println(df2.format(12.34));
System.out.println(df3.format(12.34));
System.out.println(df4.format(12.34));
结果:
12.3
12.3
012.340
12.34
double data = 1203.405607809;
// 可以在模式后加上自己想要的任何字符,比如单位
pattern = "00000000.000kg";//00001203.406kg
方式三:因为获得是String,所以保留两位小数的话,可以是1.00
[java] view plain copy
- double d = 3.1415926;
- String result = String .format(”%.2f”,F);
- %.2f %. 表示 小数点前任意位数 2 表示两位小数 格式后的结果为f 表示浮点型。 F表示对于的数字
此外如果使用struts标签做输出的话,有个format属性,设置为format="0.00"就是保留两位小数
例如:
[java] view plain copy
- <bean:write name="entity" property="dkhAFSumPl" format="0.00" />
- 或者
- <fmt:formatNumber type="number" value="${10000.22/100}" maxFractionDigits="0"/>
- maxFractionDigits表示保留的位数
BigDecimal的不可变性和算数操作
如果你定义了一个”2.00”的BigDecimal,那么”2.00”则永远都不会变
加减乘除的操作会返回一个新的BigDecimal对象(add,subtract,multiply,divide)
常用操作:
(一)BigDecimal类的常用的几个构造方法
- BigDecimal(int):将int表示形式转换为BigDecimal对象
- BigDecimal(String) :将字符串表示形式转换为BigDecimal对象
- BigDecimal(double):将double表示形式转换为BigDecimal对象
(二)BigDecimal类的常用方法
- add(BigDecimal):BigDecimal对象中的值相加,返回BigDecimal对象
- subtract(BigDecimal):BigDecimal对象中的值相减,返回BigDecimal对象
- multiply(BigDecimal):BigDecimal对象中的值相乘,返回BigDecimal对象
- divide(BigDecimal):BigDecimal对象中的值相除,返回BigDecimal对象
- toString():将BigDecimal对象中的值转换成字符串
- doubleValue():将BigDecimal对象中的值转换成双精度数
- floatValue():将BigDecimal对象中的值转换成单精度数
- longValue():将BigDecimal对象中的值转换成长整数
- intValue():将BigDecimal对象中的值转换成整数
解决之道:就是给divide设置精确的小数点divide(xxxxx,newScale,roundingMode) newScale:小数位数 roundingMode: 舍入方法
下面分享一个用于高精确处理常用的数学运算类
package com.per.test;
import java.math.BigDecimal;
/**
* 用于高精确处理常用的数学运算
* Created by lijuan on 2016/8/27.
*/
public class ArithmeticUtils {
//默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static BigDecimal add(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.add(b2);
}
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @param scale 保留scale 位小数
* @return 两个参数的和
*/
public static String add(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供精确的减法运算
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static BigDecimal sub(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.subtract(b2);
}
/**
* 提供精确的减法运算
*
* @param v1 被减数
* @param v2 减数
* @param scale 保留scale 位小数
* @return 两个参数的差
*/
public static String sub(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static BigDecimal mul(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.multiply(b2);
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @param scale 保留scale 位小数
* @return 两个参数的积
*/
public static double mul(double v1, double v2, int scale) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return round(b1.multiply(b2).doubleValue(), scale);
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @param scale 保留scale 位小数
* @return 两个参数的积
*/
public static String mul(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位,以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示需要精确到小数点以后几位
* @return 两个参数的商
*/
public static String div(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v1);
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供精确的小数位四舍五入处理
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static String round(String v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 取余数
*
* @param v1 被除数
* @param v2 除数
* @param scale 小数点后保留几位
* @return 余数
*/
public static String remainder(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 取余数 BigDecimal
*
* @param v1 被除数
* @param v2 除数
* @param scale 小数点后保留几位
* @return 余数
*/
public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
}
/**
* 比较大小
*
* @param v1 被比较数
* @param v2 比较数
* @return 如果v1 大于v2 则 返回true 否则false
*/
public static boolean compare(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
int bj = b1.compareTo(b2);
boolean res;
if (bj > 0)
res = true;
else
res = false;
return res;
}
}
相关文章
- 暂无相关文章
用户点评