`

支付金额对不上,找零时刻,货币运算

阅读更多

12年的时候在做一个电子商城项目,一个类似淘宝卖东西的网站。

B2C 商家对用户模式。

 

说下背景
用户在平台选好商品,下订单,再进行支付。这个支付用的是第三方平台 umpay 。
使用到第三方平台就要用到接口,还有密钥+授权。涉及到支付的肯定需要高安全
然后在客服支付金额的时候出现这个问题:
订单是:60.00
支付金额:59.99
后来我去查了下数据库,有很多类似这样的脏数据。
然后向umpay确认下是不是只有我们公司才出现这个的问题,对方答复是的。
这样一来问题肯定是出现在我们发生接口的那里。因为之前这个模块不是我做的,只有去看之前同事写的代码,经过一堆的数据对比,发现一个问题
然后做了下面几个测试
public static void main(String args[]){  
                 System.out.println(3.00 - 2.10);  
}
发现输出的不是想要的0.90,而是0.8999999999999999

public static void main(String args[]){  

                System.out.println(6.00 - 5.10);  

}

发现输出的不是想要的0.90,而是0.9000000000000004
 

你可能会很天真地期望该程序能够打印出 0.90,但是它如何才能知你想要打 
印小数点后两位小数呢?  

如果你对在Double.toString 文档中所设定的将 double类型的值转换为字符串 
的规则有所了解,你就会知该程序打印出来的小数,是足以将double类型的 
值与最靠近它的临近值区分出来的最短的小数,它在小数点之前和之后都至少有 
一位。因此,看起来,该程序应该打印 0.9 是合理的。 

 

解决该问题的一种方式是使用某种整数类型,例如 int 或 long,并且以分为单 
位来执行计算。如果你采纳了此路线,请确保该整数类型大到足够表示在程序中 
你将要用到的所有值。对这里举例的谜题来说,int 就足够了。下面是我们用 int 
类型来以分为单位表示货币值后重写的println 语句。这个版本将打印出正确答 

 

解决该问题的另一种方式是使用执行精确小数运算的BigDecimal。它还可以通 
过 JDBC 与SQL DECIMAL 类型进行互操作。这里要告诫你一点: 一定要用 
BigDecimal(String)构造器,而千万不要用BigDecimal(double)。后一个构造 
器将用它的参数的 “精确”值来创建一个实例:new BigDecimal(.1)将返回一个 
表示 0.100000000000000055511151231257827021181583404541015625 的 
BigDecimal。通过正确使用BigDecimal,程序就可以打印出我们所期望的结果 
0.90:   
import java.math.BigDecimal;  
public class Test{  
        public static void main(String args[]){  
                 System.out.println(new BigDecimal("2.00").  
                 subtract(new BigDecimal("1.10")));  
        }  
}  

 

总之, 在需要精确答案的地方,要避免使用float 和 double;对于货币计算, 
要使用 int、long 或 BigDecimal。对于语言设计者来说,应该考虑对小数运算 
提供语言支持。一种方式是提供对操作符重载的有限支持,以使得运算符可以被 
塑造为能够对数值引用类型起作用,例如BigDecimal。另一种方式是提供原始 
的小数类型,就像 COBOL 与PL/I 所作的一样。
  

 
0
0
分享到:
评论

相关推荐

    简易的找零系统

    3. **找零逻辑**:当用户选择商品并进行支付时,系统需根据商品价格计算所需找零金额。这涉及到简单的减法运算,即总金额减去商品价格。 4. **找零输出**:找零阶段,系统需要决定如何组合5毛和1元的硬币以达到最小...

    最少硬币找零算法

    - 对于金额为 0 的情况,`count[j][0].Num` 设为 0,表示不需要任何硬币即可完成找零。 **2. 动态规划填充** 对于每种面值 _T_[_j_] 和每种金额 _i_,按照以下规则更新 `count[j][i]` 的值: - **情况一**:若 _i...

    参考资料-基于单片机的公交车自动找零系统设计.zip

    总的来说,基于单片机的公交车自动找零系统设计是一项集成了电子、机械和软件技术的综合性工程,对提升公共交通的效率和服务质量有着重要作用。这份参考资料将为学习者提供深入理解这一领域的宝贵资源,帮助他们掌握...

    贪心算法找零问题代码

    3. **循环处理**:遍历每个硬币面值,每次尝试用最大的硬币面值去支付,直到剩余金额不足以支付该硬币。每次成功支付,就减少剩余金额,并增加硬币总数。 4. **结束条件**:当剩余金额为0时,循环结束,此时的硬币...

    货币找零计算找给顾客固定钱数的最小货币量

    货币找零计算找给顾客固定钱数的最小货币量java 原代码

    模拟多人不同面值购票找零的多线程代码(java版)

    4. 更新现金余额,增加用户支付的金额并减去找零金额。 5. 如果找零不为零,返回找零给用户。 在多线程环境中,这些操作都需要在同步控制下进行,避免出现异常情况,如负库存或负余额。 为了进一步优化,我们可以...

    C 语言实现钱币找零问题,使用贪心算法实现

    贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即...请注意,贪心算法并不总是能得到全局最优解,但在钱币找零问题中,如果钱币面额设计合理(例如常见的1、5、10、25等),贪心算法可以保证得到最优解。

    C/C++实现贪心算法 钱币找零问题

    C/C++实现贪心算法 钱币找零问题,假设有i种纸币,Values[i]元的纸币有Counts[i]张。现在要用这些钱来支付Total元,至少要用多少张纸币?

    易语言找零巧数算法

    3. 计算找零总额:`找零总额 = 支付金额 - 商品价格` 4. 实现找零算法的循环结构,如: ``` 对于 每个 硬币 在 硬币面值 当 硬币 找零总额 可用硬币数 = 找零总额 // 硬币 找零总额 -= 可用硬币数 * 硬币 结束...

    贪心算法 找零钱

    - 参数:当前找零金额 `k` 和货币面额 `j`。 - 计算能用多少个面额 `j` 的货币进行找零。 - 特殊处理小于1但不为0的情况,确保正确找零。 - 更新剩余找零金额并输出找零详情。 #### 六、总结 通过以上介绍和...

    找零钱最佳组合的测试用例

    6. 支付金额等于商品价格,不找零。 其次,我们要考虑输出的边界情况,即找零的数量。找零面值组合应包括0至45元、46至99元以及100元以下的找零数额。对于无效输出,例如找零过多或过少,系统同样需要提供错误提示...

    用贪心算法实现购物找零(支付+找零使用最少硬币数)

    假定商店里各面值的硬币有足够多,顾客也可用多种方式支付。在1次购物中希望使用最少硬币个数。例如,1次购物需要付款0.55元,没有5角的硬币,只好用2*20+10+5共4枚硬币来付款。如果付出1元,找回4角5分,同样需要4...

    确定货币系统典范性的一种有效方法

    如果一个货币系统是典范的,那么对于任何给定的金额,都存在一种最小货币数的表示方法,即可以使用最少的货币数量来支付这个金额。在文章中,这种典范性被用来评估货币系统是否合理,以及是否能够通过特定的算法得到...

    c代码-找零计算器

    在这个找零计算器中,我们需要定义不同的变量来存储商品价格、支付金额和找零金额。例如,可以声明`int price`表示商品价格,`int payment`表示支付金额,`int change`表示找零金额。 2. **输入与输出**:C语言使用...

    电子货币探索

    电子货币还具有极高的通用性,它可以在不同的支付场景中使用,无论是线上购物、水电费缴纳还是资金转账,都能实现快速支付。此外,电子货币融合了多种金融功能,如储蓄、信贷和非现金结算,极大地简化了传统金融操作...

    自动售货机找零系统

    自动售货机找零系统是一种常见的自动化零售设备,它能够接收用户投入的货币,并根据商品的价格计算出应找回的零钱。在这个系统中,我们主要关注的是如何利用C++编程语言以及STL(Standard Template Library,标准...

    找零动态规划算法

    "找零动态规划算法"是这种思想的一个实际应用,它涉及到如何有效地计算出给予一定金额时,最少数量的硬币组合。在这里,我们将深入探讨这种算法以及如何使用C++和C语言实现。 动态规划的核心在于构建一个最优解的...

    2第二章货币和货币制度.pptx

    《第二章 货币和货币制度》\n\n货币,作为社会经济活动的重要媒介,其发展历程和职能在人类历史上占据了举足轻重的地位。本章将深入探讨货币的演进、货币的本质、货币制度及其构成要素,以及货币制度的演变。\n\n一...

    汽水找零1

    首先,我们需要明确问题的背景:柠檬水每杯售价5美元,顾客支付的金额可能是5美元、10美元或20美元,我们需要确保每次交易后都能给予顾客正确的找零。初始时,我们没有零钱,且每位顾客只购买一杯柠檬水。我们的目标...

    新苏教小学三年级下册数学公开赛课混合运算PPT学习教案.pptx

    此例中,学生需要先计算出购买两盒水彩笔的总花费,然后从支付的金额中减去这个总花费,以此求出找零的金额。这样的例子让学生在解决问题的过程中,逐步掌握混合运算的技巧。 课件中的练习题目设置也非常巧妙,从...

Global site tag (gtag.js) - Google Analytics