Swift 中的 Java BigDecimal
Posted
技术标签:
【中文标题】Swift 中的 Java BigDecimal【英文标题】:Java BigDecimal in Swift 【发布时间】:2016-08-23 20:44:46 【问题描述】:我可以使用什么数据类型来解析 Java BigDecimal
?在 Objective-C 中,可以使用NSDecimalNumber
来完成。我有 Swift 原生解决方案(不使用 NSDecimalNumber
)吗?
【问题讨论】:
只需使用NSDecimalNumber
。它在 Swift 上运行良好。
你不懂。我想要原生的 Swift 解决方案(当然,如果存在的话)。
我明白。不存在“本机”解决方案。但是NSDecimalNumber
工作正常。如果您愿意,您可以定义运算符,使其表现得更像原生解决方案,以便 +
、-
等运算符按预期工作。
@PRECover 也许你应该在你的问题中提到这一点。
【参考方案1】:
这可能不是您想要的,正如您所说的 swift-native 解决方案。
但是在 Swift 3 中,基于 NSDecimal
的旧 C-struct 被导入为 Decimal
,并且已经对其进行了很大的重新安排,说“它几乎是 Swift-native”。
let deca = 1.23 as Decimal //<- This actually may produce some conversion error, while `ExpressibleByFloatLiteral` uses `Double` as an intermediate value.
let decb = 0.01 as Decimal
print(deca + decb == 1.24) //->true
UPDATE 添加了一个简单的示例,您可以在其中找到 Double(二进制浮点系统)中的计算错误。 (在 Xcode 8 beta 6 中测试。)
let dblc = 0.000001
let dbld = 100 as Double
let dble = 0.0001
print(dblc * dbld == dble) //->false (as Double cannot represent decimal fractions precisely)
let decc = Decimal(string: "0.000001")! //<- avoiding conversion error
let decd = 100 as Decimal //<- integer literal may not generate conversion error
let dece = Decimal(string: "0.0001")!
print(decc * decd == dece) //->true
【讨论】:
Swift Decimal 只能达到 128 位精度。 @CommaToast,是的,如果这可能是一个问题,您可能需要找到另一个解决方案。这个答案是在假设在Objective - C中可以通过使用NSDecimalNumber
来完成的。【参考方案2】:
您还可以使用 j2obj,这是一个将 Java 代码转换为 Objective C 的 Google 项目,包括 BigInteger 和 BigDecimal 等所有 Java 类型。使用它,我能够制作一个 XCFramework,它将对那些原生 Java 类型的支持,包括它们来自 Java 的所有功能,整合到 Swift 中。很酷,虽然它不是一个小框架。
基本上,您只需克隆 j2objc 并在本地构建(cd 到其目录并“make dist -j8”)。然后使用框架目标创建一个新的 Xcode 项目。按照 Google 的 j2objc 站点上的步骤添加您的 J2OBJC_HOME 以构建设置并将库和标头搜索路径添加到您的新框架项目。
现在,您需要在框架的公共头文件中导入“java/math/BigDecimal.h”,并且您需要将 BigDecimal.m 所需的所有头文件及其依赖项的副本添加到框架的头文件中.
最后为硬件平台归档您的框架并为模拟器构建,然后制作一个 XCFramework,包括从归档和您的 DerivedData 构建的所有 .frameworks。
一旦您拥有 XCFramework,您就可以将其添加到它支持的架构的任何其他项目中。并从那里在代码中使用它。请注意,您必须在创建 j2bjc 类的实例之前对其进行初始化。
【讨论】:
以上是关于Swift 中的 Java BigDecimal的主要内容,如果未能解决你的问题,请参考以下文章