Swift:使用 Decimal 接受金额并进行计算

前言

前段时间项目里,涉及到支付相关,后端Java兄弟过来特地找iOS端的我们问了一个问题:我们后端用BigDecimal类型的数据类型,iOS端可以接住吗?

因为安卓和后端都是用的Java编写,所以没有什么压力,不过iOS端是Swift编写的,所以特地过来咨询了一下?

我那会想都没想,说至少可以用Double接住吧?

后端的兄弟接着问:可以保证支付时候的计算精度吗?

那一刹那我傻了。

Double与Float计算时遇到的困境

我现在playground来一段代码:

image.png

true还是false

如果根据经验,一定会说是true吧,当然如果稍微有点编程经验,都知道这是一个坑爹问题。我们看看运行结果吧:

image.png

没错,走的是false,为什么?

这里不得不提一下精度问题:

浮点数字面量在代码中是无限位的, ExpressibleByFloatLiteral 使用 init(floatLiteral:) 初始化时总会发生精度损失。

反正,在代码中这些数字并不是即见即所得,大家必须要留一个心眼。

虽然都Double类型去接住JSON的里面的数据没有问题,用于展示数据到App界面上也没有问题,不过,一旦要使用这些数据进行计算,就必须考虑使用其他类型。

我们可以看看一个完整的playground的示例:

image.png

那我们遇到这种情况到底应该使用什么类型去接数据呢?

不知道到大家是否了解OC时代的NSDecimal?

使用 Decimal 表示金额

Decimal 是可以精确表示以 10 为底数字的类型。在 Swift 中,Foundation 框架提供了桥接到 NSDecimalNumber 类的 Decimal 类型(它本身包装了 NSDecimal 结构和相关函数)。

你不用像操作 Double 或 Float 值那样担心 Decimal 值相加可能会得到奇怪的结果。

我们将上面的playground例子,将数据类型显式声明一下,再来看看运行结果:

image.png

一切都看起来正常了,符合逻辑,也符合预期。

大家如果感兴趣,可以自己点进去,看看这个Decimal类:

image.png

这里,我提供的Decimal的应用场景,只是它很小同时也是很常见的使用例子,更多的使用场景,大家可以挖掘,或者在某些场景出现问题的时候,能回想起这篇文章,就可以了。

总结

小问题上的细节,可能会导致App在运行中的各种bug。

这篇文章只是一篇经验谈,但愿可以帮助到各位就好。

自己写的项目,欢迎大家star⭐️

RxStudy:RxSwift/RxCocoa框架,MVVM模式编写wanandroid客户端。

GetXStudy:使用GetX,重构了Flutter wanandroid客户端。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MY0YU6XS' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片