电商金额计算的 4 个坑,千万注意了!

简介: 前言电商项目开发时肯定少不了金额计算,金额计算时有很多让人坑人的地方,在此记录,以免被坑。

设置标签前言

电商项目开发时肯定少不了金额计算,金额计算时有很多让人坑人的地方,在此记录,以免被坑。

public static void main (String[] args) {
  double num1 = 1;
  double num2 = 31.2;
  double num3 = 323.03;
  System.out.println (num1+num2+num3);
  /**
   * 355.22999999999996
   */
}

如上代码,3 个数值想加之后却得出了一个很长的数值。


在 java 开发中可以通过 BigDecimal 进行数值类型的计算,详细可到 BigDecimal 工具类。


数据库也是一样,mysql中有float和double类型,通过sql直接累加数据也会有精度缺失的情况。如果要精确的数值计算,要使用mysql的decimal类型。


2、包装类型比对

public static void main(String[] args) {
     Integer i1 = 100;
     Integer i2 = 100;
     Integer i3 = 200;
     Integer i4 = 200;
     System.out.println(i1==i2); // true
     System.out.println(i3==i4);  // false
}

如上代码很神奇,同样是数值比对100的时候可以通过双等号返回true。200就返回false。

这是因为Integer的valueOf()方法。

//Integer的valueOf方法
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

在[-128,128]之间的数,可以通过双等于比对成功,之外的数值就会返回一个new一个新的Integer,因此会返回false。

Double的比较就简单一点,双等于比对全是false。这是因为Double直接是返回了一个新的Double。
//Double的valueOf方法
public static Double valueOf(String s) throws NumberFormatException {
    return new Double(parseDouble(s));
}

在数值比对的时候乱的样子,那我发现他们都有eq方法,通过这个方法比对可以吗?

可以的,不管是Integer还是Double都存在一个equas方法,通过这个方法即可进行数值比对。但是这个方法不是很完美。

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

如上所示,因为太多的人都知道字符串类型不能用双等号进行比对,要用eq方法进行比对其value。这样会让很多人误以为Integer和Double类型也是如此,而且在编码的时候如上这种写法也没有报错,会认为都是100肯定会返回true。恰巧这种想法是错误的。

public boolean equals(Object obj) {
    return (obj instanceof Double)
           && (doubleToLongBits(((Double)obj).value) ==
                  doubleToLongBits(value));
}

Double的eq方法入参是Object类型,因此不管传入什么类型都不会报错。i1.equals ("100")这种就是双精度和字符进行比对,这两个永远都不可能返回true。正确的写法应该是i1.equals (100d)。


但是尽管多次提醒,但是还是会有不认真的开发小伙伴错误,因此,可以使用Double.compareTo方法,这个方法和eq方法类似,但是有编译的异常,这样可有效的提醒开发人员。

public static void main (String[] args){
  Double i1 = 100d;
  System.out.println(i1.compareTo (100d)); //0
  System.out.println(i1.compareTo (1d));  //1
}

3、除以0会怎样?

小学的时候就讲过,进行除法运算时,除以0是没有意义的,开发过程中也是如此, 发现可能存在除以0的场景要特别注意,程序不会抛出异常,竟然会返回一个字符串!虽然这种场景不多,但是还是需要了解一下。

1除以0的场景:

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

0除以0的场景:

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

4、float转double

public static void main(String[] args) {
    Float f = 12312.12f;
    System.out.println(f.doubleValue()); 
    System.out.println(Double.parseDouble (f.toString ())); 
    //12312.1201171875
    //12312.12
}

Float类中有一个doubleValue方法,返回值是一个double类型,这样会很容易的以为这是float转换double类型。但是转换之后精度缺失了,只能乖乖的换一种方式转换。


相关文章
|
1月前
银行定期存款利率,输入金额,输入年限,计算本息总额
银行定期存款利率,输入金额,输入年限,计算本息总额
36 0
|
9月前
|
算法 Java PHP
算法思考:红包金额生成
最近在整理过去的项目时,回顾了某年红包活动的项目,其中涉及红包金额计算的算法。近些年各家大厂举办的春节红包活动越来越完善,关于活动背后的整体设计介绍、分析、探讨层出不穷。本篇先不关注整体架构,选择红包金额的计算方法作为分析内容。 在当时的项目中,红包金额计算主要是采用了基于一些入参的随机数生成,并且生成的是单个红包金额,并未使用队列方式做预生成。所以再次回顾这个案例,其中其实还有很多可以玩味和深入思考的地方,在这里做一次思考总结。
77 0
|
1月前
|
数据采集 存储 数据挖掘
京东商品优惠券数据采集
京东商品优惠券数据采集
66 2
|
1月前
|
消息中间件 供应链 NoSQL
电商订单待支付(思路分析)
电商订单待支付(思路分析)
|
1月前
|
数据采集 存储 数据挖掘
拼多多商品优惠券数据采集
拼多多商品优惠券数据采集
32 0
|
1月前
leetcode-1475:商品折扣后的最终价格
leetcode-1475:商品折扣后的最终价格
33 0
|
C语言 数据安全/隐私保护
用C语言写一个商品购物收银台系统,统计购买商品总价
要制作一个“系统”,就得先把一个个小功能逐一实现,然后将其整合,我们用C语言只需把它们写成一个个函数即可,直接进入正题,我们列出今天所需的头文件,一共五个。
|
机器学习/深度学习
某销售公司在年末的时候会向员工发放红包,发放的红包金额共有5种,获取的条件各不相同:   1) 五颗星红包,每人8000元,平均月绩效大于80件商品(>80),并且在本年度满勤; 2) 四颗星红包,每
某销售公司在年末的时候会向员工发放红包,发放的红包金额共有5种,获取的条件各不相同:   1) 五颗星红包,每人8000元,平均月绩效大于80件商品(>80),并且在本年度满勤; 2) 四颗星红包,每
207 0
|
安全 NoSQL Redis
【浅谈电商】如何防止重复支付
一、前言 最近正在做电商相关的项目,整理一下解决方案并帮助自己巩固知识点,此方案是结合了目前的业务环境,若有更好的解决的方式很高兴与大家一起讨论。
341 0
【浅谈电商】如何防止重复支付
|
JavaScript 前端开发
使用 JavaScript 根据消费金额和消费者是否为会员确定折扣,最终核算实际应该支付的金额
使用 JavaScript 根据消费金额和消费者是否为会员确定折扣,最终核算实际应该支付的金额
415 0
使用 JavaScript 根据消费金额和消费者是否为会员确定折扣,最终核算实际应该支付的金额

热门文章

最新文章