前言
前段时间项目里,涉及到支付相关,后端Java兄弟过来特地找iOS端的我们问了一个问题:我们后端用BigDecimal
类型的数据类型,iOS端可以接住吗?
因为安卓和后端都是用的Java编写,所以没有什么压力,不过iOS端是Swift编写的,所以特地过来咨询了一下?
我那会想都没想,说至少可以用Double接住吧?
后端的兄弟接着问:可以保证支付时候的计算精度吗?
那一刹那我傻了。
Double与Float计算时遇到的困境
我现在playground来一段代码:
走true
还是false
?
如果根据经验,一定会说是true吧,当然如果稍微有点编程经验,都知道这是一个坑爹问题。我们看看运行结果吧:
没错,走的是false,为什么?
这里不得不提一下精度问题:
浮点数字面量在代码中是无限位的,
ExpressibleByFloatLiteral
使用init(floatLiteral:)
初始化时总会发生精度损失。
反正,在代码中这些数字并不是即见即所得,大家必须要留一个心眼。
虽然都Double类型去接住JSON的里面的数据没有问题,用于展示数据到App界面上也没有问题,不过,一旦要使用这些数据进行计算,就必须考虑使用其他类型。
我们可以看看一个完整的playground的示例:
那我们遇到这种情况到底应该使用什么类型去接数据呢?
不知道到大家是否了解OC时代的NSDecimal?
使用 Decimal 表示金额
Decimal 是可以精确表示以 10 为底数字的类型。在 Swift 中,Foundation 框架提供了桥接到 NSDecimalNumber
类的 Decimal
类型(它本身包装了 NSDecimal
结构和相关函数)。
你不用像操作 Double
或 Float
值那样担心 Decimal
值相加可能会得到奇怪的结果。
我们将上面的playground例子,将数据类型显式声明一下,再来看看运行结果:
一切都看起来正常了,符合逻辑,也符合预期。
大家如果感兴趣,可以自己点进去,看看这个Decimal类:
这里,我提供的Decimal
的应用场景,只是它很小同时也是很常见的使用例子,更多的使用场景,大家可以挖掘,或者在某些场景出现问题的时候,能回想起这篇文章,就可以了。
总结
小问题上的细节,可能会导致App在运行中的各种bug。
这篇文章只是一篇经验谈,但愿可以帮助到各位就好。
自己写的项目,欢迎大家star⭐️
RxStudy:RxSwift/RxCocoa框架,MVVM模式编写wanandroid客户端。
GetXStudy:使用GetX,重构了Flutter wanandroid客户端。