博客
关于我
【电商吧 - 4】电商场景数值计算那些坑
阅读量:483 次
发布时间:2019-03-07

本文共 2830 字,大约阅读时间需要 9 分钟。

电商项目开发中的金额计算注意事项

在电商项目开发中,金额计算作为核心功能之一,常常面临着多个坑点。本文将从实际开发中总结出的几类常见问题,并给出相应的解决方案,不仅让开发过程更顺畅,还能避免因小失误导致重大问题。


1. 多精度计算问题

在日常开发中,使用double类型进行计算时,可能会出现精度丢失的问题。虽然double类型的精度比float高,但在某些场景下,特别是需要高精度arithmetics时,仍然会存在精度溢出的风险。

示例代码

public static void main(String[] args) {    double num1 = 1;     //double型变量    double num2 = 31.2; //double型变量    double num3 = 323.03; //double型变量    System.out.println(num1 + num2 + num3);  //输出结果:355.22999999999996}

问题分析

  • 精度缺失:在浮点数运算中,某些操作可能导致数值的精度丢失。例如,浮点数的加法运算会使得结果的小数点逐渐往后移动,直到达到 floating-point precision limit。
  • 解决方案:在开发中,当需要高精度计算时,应使用BigDecimal类型。对于数据库部分,建议使用DECIMAL类型,而不是floatdouble

注意:要注意输入的数据格式,也要避免传递字符串直接转换为数值型。


2. 包装类型的比对问题

在 Java 开发中,使用包装类型进行值的比较时,我们需要了解不同包装类型的equalscompareTo方法的实现机制。

比较案例

public static void main(String[] args) {    Integer i1 = 100;   //autoboxed为Integer类型    Integer i2 = 100;   //autoboxed为Integer类型    Integer i3 = 200;   //autoboxed为Integer类型    Integer i4 = 200;   //autoboxed为Integer类型        System.out.println(i1.equals(i2));   //返回true,i3和i4也返回true?    System.out.println(i3.equals(i4));   //返回false    System.out.println(i1.equals(100));  //返回false    System.out.println(i1.equals("100")); //返回false}

问题分析

  • Integer的valueOf方法Integer.valueOf(int)方法会调用的IntegerCache, 只有在[-128, 128]范围内的整数才会使用缓存实例,否则会返回一个新的Integer对象。
  • Double的valueOf方法Double.valueOf(String s)方法会直接构造一个新的Double对象,而不会与传入参数比较真实值。

知道的不足

  • 错误的假设Double i1 = 100d; i1.equals("100")会返回false,因为类型不同。
  • 正确写法i1.equals(100d)才会返回true。

解决方案:在处理比较时,使用compareTo方法,或者使用Objects.equals方法来确保比较的准确性。

代码示例(不安全)

public static void main(String[] args) {    Double d1 = 100d;    Double d2 = 100d;        System.out.println(d1.equals(d2));  //返回true    System.out.println(d1.equals("100")); //返回false}

3. 除以0的处理

在程序中如果遇到除以0的情况,结果会有不同的表现。

1. 1 除以 0 的情况

public static void main(String[] args) {    double d = 1d;    double v = d / 0d;    System.out.println(v);  //输出:Infinity}

2. 0 除以 0 的情况

public static void main(String[] args) {    double d = 0d;    double v = d / 0d;    System.out.println(v);  //输出:NaN}

问题分析

  • Infinity:表示结果是一个无穷大。
  • NaN:表示结果是一个非数(Not a Number),无意义。

解决方案:在项目中,应对除以0的情况进行特别处理,避免抛出错误或默认值。


4. Float 转 Double 的精度问题

有些开发者以为通过Float转换到Double就能解决精度问题,但实际效果可能不如预期。

示例代码

public static void main(String[] args) {    Float f = 12312.12f;  //声明一个Float变量    Double d = f.doubleValue();  //Float->Double转换    System.out.println(d);              //12312.1201171875        Double d2 = Double.parseDouble(f.toString());  //转换方式二    System.out.println(d2);              //12312.12}

问题分析

  • Float 转 DoubleFloat.doubleValue()方法返回的精度可能不如预期,部分小数位会被丢失。
  • 字符串转换f.toString()会丢失一些精度信息,导致转换后的结果精度不如原始值。

知道的不足

  • 浮点数精度限制:无论是Float还是Double,都有限制,具体取决于计算架构(如 IEEE 754)。

解决方案

  • 避免使用Float类型:在不需要高效率时,应直接使用Double类型。
  • 精确数据传输:在数据存储或传输时,应使用字符串或者BigDecimal类型。

总结

电商项目开发过程中,金额计算涉及到的问题无处不在。如果不予以重视,不仅会导致计算错误,还可能引发严重的问题。掌握这些常见问题及解决方案,可以让开发工作更加可靠,也避免项目出手就烂的尴尬局面。

转载地址:http://ibgdz.baihongyu.com/

你可能感兴趣的文章
Nginx负载均衡和F5的区别---系统运维工作笔记001
查看>>
nginx负载均衡和反相代理的配置
查看>>
nginx负载均衡器处理session共享的几种方法(转)
查看>>
nginx负载均衡的5种策略
查看>>
nginx负载均衡的5种策略(转载)
查看>>
nginx负载均衡的五种算法
查看>>
Nginx负载均衡(upstream)
查看>>
nginx转发端口时与导致websocket不生效
查看>>
Nginx运维与实战(二)-Https配置
查看>>
Nginx部署_mysql代理_redis代理_phoenix代理_xxljob代理_websocket代理_Nacos代理_内网穿透代理_多系统转发---记录021_大数据工作笔记0181
查看>>
Nginx配置HTTPS服务
查看>>
Nginx配置Https证书
查看>>
Nginx配置http跳转https
查看>>
Nginx配置ssl实现https
查看>>
nginx配置ssl证书https解决公网ip可以访问但是域名不行的问题
查看>>
Nginx配置TCP代理指南
查看>>
NGINX配置TCP连接双向SSL
查看>>
Nginx配置——不记录指定文件类型日志
查看>>
nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
查看>>
nginx配置中的服务器名称
查看>>