double进行四舍五入

一、故障现象

排行榜中出现同一物品的评分不同

物品A原为8.5    排行榜中8分

二、导致原因

在查询数据库时,使用mysql 函数对rate 字段进行了处理 round(rate,1) 小数点后 保留一位,

在mysql中,round函数用于数据的四舍五入,它有两种形式:

1、round(x,d)  ,x指要处理的数,d是指保留几位小数

这里有个值得注意的地方是,d可以是负数,这时是指定小数点左边的d位整数位为0,同时小数位均为0;

而在查询排行榜是没有做如上处理

三、解决方案

在查询排行榜时对物品的评分使用 java 进行四舍五入

四 、优化建议

方法一:使用字符串格式化实现四舍五入(支持float和double类型)
  		double data = 3.02;
        //利用字符串格式化的方式实现四舍五入,保留1位小数
        String result = String.format("%.1f",data);
        //1代表小数点后面的位数, 不足补0。f代表数据是浮点类型。保留2位小数就是“%.2f”,依此累推。
        System.out.println(result);//输出3.0

方法二:使用BigDecimal实现四舍五入(支持float和double类型)
  		double data = 3.02;
        //利用BigDecimal来实现四舍五入.保留一位小数
        double result = new BigDecimal(data).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
        //1代表保留1位小数,保留两位小数就是2,依此累推
        //BigDecimal.ROUND_HALF_UP 代表使用四舍五入的方式
        System.out.println(result);//输出3.0
1
2
3
4
5
6
方法三:使用DecimalFormat实现四舍五入(仅支持float类型)
		DecimalFormat decimalFormat=new DecimalFormat("#.##");
		//保留2位小数,.后面的#代表小数点后面的位数,保留3位小数就是#.###
		System.out.println(decimalFormat.format(3.065f));//输出3.07
		System.out.println(decimalFormat.format(3.065));//double类型,输出3.06
————————————————
版权声明:本文为CSDN博主「devnn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/devnn/article/details/83104228

方法 四:   使用  BigDecimal的round 方法  实现四舍五入

long start4 = System.nanoTime();
BigDecimal  bigDecimal = new BigDecimal("7.08");
MathContext mathContext = new MathContext(2, RoundingMode.HALF_UP);
// 保留小数点后一位小数
double v1 = bigDecimal.round(mathContext).doubleValue();
long end4 = System.nanoTime();
System.out.println(v1+"============"+(end4-start4));
第四种的速度最快
round()在四舍五入时可能会引发异常。
源自
https://blog.csdn.net/cumtb2009/article/details/107795748


package com.test;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDateTime;

/**
 * @Author yanming
 * @Description
 * @Date 2021/9/22 17:32
 */
public class NumberFormat {

public static void main(String[] args) {
    long start = System.nanoTime();
    double  number = 7.08;
    String format = String.format("%.1f", number);
    long end = System.nanoTime();
    System.out.println(format+"============"+(end-start));
    long start1 = System.nanoTime();
    double  number2 = 7.08;
    double v = new BigDecimal(number2).setScale(1, BigDecimal.ROUND_HALF_DOWN).doubleValue();
    long end1 = System.nanoTime();
    System.out.println(v+"============"+(end1-start1));

    long start2 = System.nanoTime();
    double  number3 = 7.08;
    DecimalFormat decimalFormat = new DecimalFormat("#.#");
    String format1 = decimalFormat.format(number3);
    long end2 = System.nanoTime();
    System.out.println(format1+"============"+(end2-start2));

    long start4 = System.nanoTime();
    BigDecimal  bigDecimal = new BigDecimal("7.08");
    MathContext mathContext = new MathContext(2, RoundingMode.HALF_UP);
    double v1 = bigDecimal.round(mathContext).doubleValue();
    long end4 = System.nanoTime();
    System.out.println(v1+"============"+(end4-start4));
}


//
//        7.1============17125900
//        7.1============1985900
//        7.1============1299700
//        7.1============68300

}

关于RoundingMode是一个数字精度的舍入枚举,通过不同的舍入模式,获得不同的舍入结果

UP(BigDecimal.ROUND_UP),
//向上舍入   大于2 的为 3   2.01    3   
// -1.6  -1
// -1.0  -1
DOWN(BigDecimal.ROUND_DOWN),
//  向下舍入   大于2 小于3.0 的为 2
//  2.99   2
// -1.6   -2
// -1.0   -1
CEILING(BigDecimal.ROUND_CEILING),
// 如果是正数 ,则向上舍入   如果是负数 ,则向下舍入
//2.1     3
//0.0      0
//-1.2     -2
FLOOR(BigDecimal.ROUND_FLOOR),
// 如果是正数,则向下舍入  ,如果是负数,则向上舍入
//5.5    5
// 5.9   6
//-1.1   -1`
//-1.6   -
HALF_UP(BigDecimal.ROUND_HALF_UP),
// 四舍五入
HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
// 如果要舍弃的部分 大于0.5 则向上取.负责向下取值
//  5.5  5
// 5.6    6
//-1.5      -1
//-1.6    -2
HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
// 向偶数部分取值
//  5.5    6
//  2.5   3
//  -1.6   -2
//  -2.5    -2
UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
// 舍入模式的断言操作,如果需要舍入则抛出异常 ArithmeticException
// -1.2  ArithmeticException
//2.2   ArithmeticException
//-1.0   -1
// 1.0    1

关于RoundingMode是一个数字精度的舍入枚举,通过不同的舍入模式,获得不同的舍入结果

UP(BigDecimal.ROUND_UP), //向上舍入 大于2 的为 3 2.01 3 // -1.6 -1 // -1.0 -1 DOWN(BigDecimal.ROUND_DOWN), // 向下舍入 大于2 小于3.0 的为 2 // 2.99 2 // -1.6 -2 // -1.0 -1 CEILING(BigDecimal.ROUND_CEILING), // 如果是正数 ,则向上舍入 如果是负数 ,则向下舍入 //2.1 3 //0.0 0 //-1.2 -2 FLOOR(BigDecimal.ROUND_FLOOR), // 如果是正数,则向下舍入 ,如果是负数,则向上舍入 //5.5 5 // 5.9 6 //-1.1 -1` //-1.6 - HALF_UP(BigDecimal.ROUND_HALF_UP), // 四舍五入 HALF_DOWN(BigDecimal.ROUND_HALF_DOWN), // 如果要舍弃的部分 大于0.5 则向上取.负责向下取值 // 5.5 5 // 5.6 6 //-1.5 -1 //-1.6 -2 HALF_EVEN(BigDecimal.ROUND_HALF_EVEN), // 向偶数部分取值 // 5.5 6 // 2.5 3 // -1.6 -2 // -2.5 -2 UNNECESSARY(BigDecimal.ROUND_UNNECESSARY); // 舍入模式的断言操作,如果需要舍入则抛出异常 ArithmeticException // -1.2 ArithmeticException //2.2 ArithmeticException //-1.0 -1 // 1.0 1

你可能感兴趣的:(java,数据库)