当前位置: 首页 > 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
  1. double   f   =   111231.5585;  
  2. BigDecimal   b   =   new   BigDecimal(f);  
  3. 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
  1. java.text.DecimalFormat   df   =new   java.text.DecimalFormat("#.00");  
  2. 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
  1. double d = 3.1415926;  
  2.   
  3. String result = String .format(”%.2f”,F);  
  4.   
  5. %.2f %. 表示 小数点前任意位数   2 表示两位小数 格式后的结果为f 表示浮点型。  F表示对于的数字
      方式四:

      此外如果使用struts标签做输出的话,有个format属性,设置为format="0.00"就是保留两位小数

      例如:

[java]  view plain copy
  1. <bean:write name="entity" property="dkhAFSumPl"  format="0.00" />  
  2.   
  3. 或者  
  4.   
  5. <fmt:formatNumber type="number" value="${10000.22/100}" maxFractionDigits="0"/>  
  6.   
  7. 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对象中的值转换成整数
通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常的

解决之道:就是给divide设置精确的小数点divide(xxxxx,newScale,roundingModenewScale:小数位数 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;}
}
http://www.xdnf.cn/news/11391.html

相关文章:

  • 什么是scrum里的3355
  • PHP中 stripslashes() 函数 和 addslashes() 函数
  • 2024计算机最吃香的几大专业,哪些好就业?
  • 对于过滤器中使用getInputStream()、getParameter()接收参数接收不到的一些知识,以及解决方法。
  • TLSF算法概念,原理,内存碎片问题分析
  • UML 类关系(详解)——依赖、关联、聚合、组合、泛化
  • “IT小百科”之“电脑开机密码忘记了怎么办”
  • mentohust 使用
  • 打造优质的灵修生活
  • ActiveSync同步使用方法
  • OGG|Oracle GoldenGate 基础知识介绍(二)
  • 介绍一个很不错的电影网站
  • css实现两端对齐的3种方法
  • 机动战士高达观影顺序
  • 光耦合器知识概述
  • HTTP 和 HTTPS 的区别(面试常考题),计算机专业学生必备
  • 堆栈溢出
  • (译)追本溯源 —— C之精神
  • JAVA常用类—————StringTokenizer类
  • 重磅发布!吴恩达 AI 完整课程资源超级大汇总!
  • 微信web开发者工具
  • .wav文件详解,PCM数据格式,.wav生成C语言数组
  • Oracle数据库导入工具IMP详解与用法
  • java porm.xml_如何通过Maven仓库安装Spire系列的Java产品
  • java复习 02
  • 苹果CMS采集资源站
  • cognos入门
  • random()随机函数
  • System V消息队列报Resource temporarily unavailable 错误
  • C#-TimeSpan格式化字符串格式