RoundedDecimal 2.2.0

RoundedDecimal 2.2.0

SoftwareEngineerChris 维护。



  • SoftwareEngineerChris

RoundedDecimal

Build Status Cocoapods SPM

RoundedDecimal 有两种口味;RoundedDecimal<T: DecimalPlaces>DynamicRoundedDecimal。不同的情况需要使用其中之一。

RoundedDecimal<T: DecimalPlaces>

Swift 小数,小数位数是类型的一部分。例如,RoundedDecimal<Places.five> 只能与其它 RoundedDecimal<Places.five> 值一起操作。这是在编译时保证的,但需要开发者事先知道需要哪种级别的精度。

示例

// listedPrice == 2.59
let listedPrice: RoundedDecimal<Places.two> = "2.5872659"

// exchangePrice == 1.12345
let exchangeRate: RoundedDecimal<Places.five> = "1.1234528492"

let localPrice = listedPrice * exchangeRate

将导致编译失败

binary operator '*' cannot be applied to operands of type 'RoundedDecimal<Places.two>' and 'RoundedDecimal<Places.five>'
let localPrice = listedPrice * exchangeRate
~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~    

这些情况可以进行处理,但在乘法允许之前,开发者必须明确决定结果的精度。请参阅 RoundedDecimal 的文档获取更多信息。

DynamicRoundedDecimal

当所需的十进制位数在编译时无法确定时,此类类型非常有用。例如,处理在运行时决定且具有不同十进制位数的任意货币时。例如,美元有两位小数,但日元没有小数。在这种情况下,DynamicRoundedDecimal 非常合适,因为构造时提供了所需的十进制位数。

示例

// listedPrice == 2.59 after using a scale of 2 to represent USD
let listedPrice = DynamicRoundedDecimal(stringLiteral: "2.5872659", scale: 2)

// exchangePrice == 108.09364 after using a scale of 5
let exchangeRate = DynamicRoundedDecimal(stringLiteral: "108.0936412", scale: 5)

// localPrice = 279.96253 which uses the largest scale of either decimal, 5 in this case
let localPrice = listedPrice * exchangeRate

// appropriateLocalPrice = 280 after using a scale of 0 to represent JPY
let appropriateLocalPrice = localPrice.with(scale: 0)

安装

CocoaPods

pod 'RoundedDecimal', '~> 2.2.0'

Swift 包管理器

dependencies: [
  .package(url: "https://github.com/SoftwareEngineerChris/RoundedDecimal.git", from: "2.2.0")
]

为什么

简略来说:我们希望保证小数精度,或者在更改精度时明确。

在处理小数时,我们经常想知道对我们的数值所代表的小数位数进行操作、处理或维护。

例如,在一个面向英国和美国的购物应用中处理货币时,我们希望处理具有两位小数的数字。特别是在处理大量的这些数字并将美元与英镑之间进行转换时。

如果我们有一个在美国售价为 $2.50 的产品,并且我们想在英国销售它,我们可能希望使用汇率来计算本地价格。如果我们的 API 提供的汇率是 0.81245 USD/GBP (或 1.23084 GBP/USD),通过简单的乘法,我们可以计算出产品的价格是 £3.0771

我们可能不希望将£3.0771呈现给用户,因为他们通常不会以便士的分数进行交易。在我们的显示层中,我们可能在收据中将该值格式化为£3.08。用户已经决定订购300件这样的商品。我们的应用程序的计算部分不一定知道数据是如何呈现的,因此处理£3.0771的商品价格。因此,£3.0771乘以300等于£923.13

在这种情况下,我们可能向用户展示如下收据:特殊商品 @ £3.08 x 300 = £923.13

但是300乘以£3.08并不等于£923.13。而是等于£924.00。用户对他们看到的总计感到困惑,没有意识到使用的计算价格是每件£3.0771,而不是显示的£3.08

他们在收据上应该看到的是以下之一:特殊商品 @ £3.08 x 300 = £924.00特殊商品 @ £3.0771 x 300 = £923.13

如何处理这一问题应该是一个业务决策,但我们应该能够保证代码中该决策的结果。如果使用的货币或至少所需的十进制长度在编译时是静态且已知的,我们可以使用RoundedDecimal来将其作为一个编译时的要求。或者,如果我们在运行时处理货币或十进制长度,我们可以使用DynamicRoundedDecimal来处理这种情况。查看每种类型的文档以了解如何进行这种处理。