当前位置: 首页 > news >正文

天津智能网站建设学校做网站

天津智能网站建设,学校做网站,合肥公司企业网站建设,网址浏览器背景 在之前的开发过程中, 遇到了一些小问题. 就是在某功能计算时, 按照当时的设想是需要保留两位小数并向下取整. 当时没有太好的思路, 于是请教了好朋友gpt同志. 而gpt给出3种思路: 使用String.format方法 double value 123.456789; String formattedString String.forma…背景 在之前的开发过程中, 遇到了一些小问题. 就是在某功能计算时, 按照当时的设想是需要保留两位小数并向下取整. 当时没有太好的思路, 于是请教了好朋友gpt同志. 而gpt给出3种思路: 使用String.format方法 double value 123.456789; String formattedString String.format(%.2f, value); System.out.println(formattedString); // 输出 123.46DecimalFormat import java.text.DecimalFormat; double value 123.456789; DecimalFormat decimalFormat new DecimalFormat(#.##); String formattedString decimalFormat.format(value); System.out.println(formattedString); // 输出 123.46如果你只是想要进行数值计算并且想要得到一个近似到两位小数的double值而不是字符串表示那么你可以使用Math.round方法配合乘以100、除以100的操作 double value 123.456789; double roundedValue (double) Math.floor(value * 100) / 100; System.out.println(roundedValue); // 输出可能接近 123.46 但可能由于精度问题不完全相等当时由于业务需要计算选择了思路3, 当时天真的以为精度肯定不会对自己的业务造成影响. 因为自己只计算简单的求和以及平均值计算, 应该不会有啥大问题 可没想还是绳子专挑细处断, 再一次体验到墨菲定律… 问题描述 将主要业务问题抽象成代码表示就是: 需要将Double类型集合求平均值, 然后根据实际的count数计算出总和评分, 需要向下取整并保留两位小数 public static void main(String[] args) {//23D-23 BigDecimal 出现了精度丢失ListDouble list Arrays.asList(1D,4D,3D,3D,3D,3D,1D,1D,2D,2D);System.out.println(calculateAverage(list)); //2.30//这里指的是数据库中没有数据, 即只有当前数据long count 1;Double rating (calculateAverage(list).doubleValue() / count) * 100;System.out.println(rating); //229.99999999999997System.out.println(Math.floor(rating)/100); //2.29}/*** 求出list中数组的平均值* param numberList* return*/public static BigDecimal calculateAverage(ListDouble numberList) {if (numberList null || numberList.isEmpty()) {throw new IllegalArgumentException(传入数组不能为空);}int sum 0;for (Double number : numberList) {sum number;}BigDecimal bd new BigDecimal(String.valueOf((double) sum / numberList.size()));bd bd.setScale(2, RoundingMode.FLOOR); // 保留两位小数向下取整return bd;}可以看到Double类型的数值 2.3D在乘以100之后结果不是预想中的230, 而是 229.99999999999997 而且, 在将2.3D依次乘以1, 10, 100, 1000 时, 唯有在乘以100的时候出现了精度丢失 到底是为什么呢? 经过查阅资料 java数值范围以及float与double精度丢失问题 后, 从下面这部分我看到了 //举例 double result 1.0 - 0.9; //0.09999999999999998这是java和其它计算机语言都会出现的问题下面我们分析一下为什么会出现这个问题 float和double类型主要是为了科学计算和工程计算而设计的。他们执行二进制浮点运算这是为了在广泛的数字范围上提供较为精确的快速近似计算而精心设计的。然而它们并没有提供完全精确的结果所以我们不应该用于精确计算的场合。float和double类型尤其不适合用于货币运算因为要让一个float或double精确的表示0.1或者10的任何其他负数次方值是不可能的其实道理很简单十进制系统中能不能准确表示出1/3呢同样二进制系统也无法准确表示1/10。 浮点运算很少是精确的只要是超过精度能表示的范围就会产生误差。往往产生误差不是因为数的大小而是因为数的精度。因此产生的结果接近但不等于想要的结果。尤其在使用 float 和 double 作精确运算的时候要特别小心。 我的理解就是float和double在计算时, 都会转换成二进制计算 由于小数点后面的数在转换成二进制后, 很多都无法转换成有限位二进制数, 例如: 0.3-0.0100110011001100110011001100110011001100110011001101 (如下图结果是无限循环,只是执行到指定位数不进行显示了) 然后我们反过来将二进制转化成十进制进行计算, 可以看到得出的只是近似且无限接近 0.3 的值 因此在进行计算时精度会有不同程度的丢失. 所以就会在计算时得到我们所不期望的很长为数的小数(0.30000000000000004) 即在进行带有小数的double或者float数值进行计算(加减乘除)时, 因为精度的原因会导致数据结果有误 故float或者double在进行浮点数运算时, 一般只能无限但接近我们数学运算得到的结果! 解决方案 将小数点部分也完全按照整数进行存储和计算 //举例 double result 1.0 - 0.9; //0.09999999999999998 //需要保留一位小数时, 结果统一乘10再除以10 double result (10-9)/10使用BigDecmal进行加减乘除 需要注意的是创建BigDecimal最好是使用字符串。否则也有可能出现精度丢失问题例如上面说的0.58*100如果不是字符串依然精度丢失. //修改后进行计算BigDecimal countB new BigDecimal(1);BigDecimal ratingB new BigDecimal(2.3);BigDecimal dotNum new BigDecimal(100);System.out.println(ratingB.divide(countB).multiply(dotNum).setScale(2, RoundingMode.FLOOR).divide(dotNum).doubleValue()); //2.3利用工具类, 封装计算方法, 将两个传入的double值进行计算 double div BigDecimalUtils.div(2.3, 1, 2, BigDecimal.ROUND_FLOOR); double mul BigDecimalUtils.mul(div, 100); double mul2 BigDecimalUtils.div(mul, 100); System.out.println(mul mul); //mul 230.0 System.out.println(mul2 mul2); //mul2 2.3附工具类代码 下面是对double进行浮点运算的工具类代码 没有特别对float的运算封装成工具类, 因此使用时可以将float转成double来进行计算 import java.math.BigDecimal;/*** info:提供对double类型参数进行各种浮点运算的工具类** Author chy* Date 2024/07/09 16:44*/ public class BigDecimalUtils {/*** 默认除法运算精度为小数点后两位*/private static final int DEF_DIV_SCALE 2;private BigDecimalUtils() {}/*** 提供精确的加法运算** 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 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 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 乘数* param scale 表示表示需要精确到小数点以后几位。* param roundingMode 舍入模式: {link java.math.BigDecimal#ROUND_UP}* return 两个参数的积*/public static double mul(double v1, double v2, int scale, int roundingMode) {BigDecimal b1 new BigDecimal(Double.toString(v1));BigDecimal b2 new BigDecimal(Double.toString(v2));return b1.multiply(b2).setScale(scale, roundingMode).doubleValue();}/*** 提供相对精确的除法运算精确到小数点以后2位默认进行四舍五入** param v1 被除数* param v2 除数* return 两个参数的商*/public static double div(double v1, double v2) {return div(v1, v2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP);}/*** 提供各种舍入模式的的除法运算。当发生除不尽的情况时由scale参数指定精度** param v1 被除数* param v2 除数* param scale 表示表示需要精确到小数点以后几位。* param roundingMode {link java.math.BigDecimal#ROUND_UP}* return 两个参数的商*/public static double div(double v1, double v2, int scale, int roundingMode) {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, roundingMode).doubleValue();}/*** 提供精确的小数位四舍五入处理。** 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));BigDecimal one new BigDecimal(1);return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();} };
http://www.pierceye.com/news/738777/

相关文章:

  • 武城网站建设费用网页设计试题及答案
  • 郑州外贸网站建设公司搜索引擎排名的三大指标
  • 温州专业微网站制作电台 主题 wordpress
  • wordpress做网站过程阳江网上车管所
  • 网站抓取qq上海自贸区注册公司流程
  • 深圳网站设计推荐刻烟台制作网站有哪些
  • 网站注册系统源码卢松松博客源码 wordpress博客模板
  • 网站开发进阶实训报告廊坊安次区网站建设公司
  • jquery插件网站推荐打开网站自动跳转代码
  • 佛山顺德容桂网站制作写作平台
  • 网站源码下载pdf文件品质好房
  • 山网站建设长沙网站开发湖南微联讯点不错
  • 网站建设的方案模板邢台123今天的招聘信息
  • 一个网站做app网站如何做收款二维码
  • 济南seo网站优化网站开发源代码 百度文库
  • 东西湖区建设局网站制作网站需要钱吗
  • 自己买服务器能在wordpress建网站欧美色影网站
  • 网站支付页面设计金华企业网站建设公司
  • wordpress评论模块临沂seo网站管理
  • 四川法制建设网站产品推广步骤
  • 服务器 网站建设比较容易做流量的网站
  • 网站建设基础实训报告天津滨海新区地图全图
  • 兰西网站建设深圳58同城招聘网
  • 兰州网站建设程序烟台赶集网网站建设
  • 自己建立网站后怎么做淘客wordpress需要npv
  • 简单网站建设推荐wordpress主题ashley
  • 单页网站开发实例下载电商营销渠道有哪些
  • 沈阳科技网站首页东营市做网站
  • 网站移动端开发公司客户评价网站建设
  • 有没有做问卷还能赚钱的网站鲜花网站数据库建设