Swift 3中的十进制到双精度转换

Zap*_*hod 29 migration type-conversion ios swift swift3

我正在将一个项目从Swift 2.2迁移到Swift 3,我试图在可能的情况下摆脱旧的Cocoa数据类型.

我的问题在这里:迁移NSDecimalNumberDecimal.

我用来桥接NSDecimalNumberDouble这两种方式雨燕2.2:

let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)

let doubleFromDecimal = decimalNumber.doubleValue
Run Code Online (Sandbox Code Playgroud)

现在,切换到Swift 3:

let double = 3.14
let decimal = Decimal(double)

let doubleFromDecimal = ???
Run Code Online (Sandbox Code Playgroud)

decimal.doubleValue不存在,Double(decimal)甚至不存在decimal as Double......我想出的唯一一个黑客是:

let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue
Run Code Online (Sandbox Code Playgroud)

但是试图摆脱NSDecimalNumber它并且必须偶尔使用它将是完全愚蠢的......

好吧,要么我错过了一些明显的东西,请原谅浪费你的时间,或者在我看来需要解决一个漏洞......

在此先感谢您的帮助.

编辑:在Swift 4上没有关于这个主题的更多信息.

rma*_*ddy 14

在Swift 3中工作的另一个解决方案是Decimal转换NSNumber并创建Double它.

let someDouble = Double(someDecimal as NSNumber)
Run Code Online (Sandbox Code Playgroud)

  • `在Swift 4中让c = Double(截断:a as NSNumber) (4认同)

ske*_*ech 10

NSDecimalNumber并且Decimal是桥接的

Swift覆盖到Foundation框架提供了Decimal结构,该结构桥接到NSDecimalNumber类.Decimal值类型提供与NSDecimalNumber引用类型相同的功能,并且这两者可以在与Objective-C API交互的Swift代码中互换使用.此行为类似于Swift如何将标准字符串,数字和集合类型桥接到其对应的Foundation类.Apple Docs

但与其他一些桥接类型一样,缺少某些元素.

要重新获得功能,您可以编写扩展程序:

extension Decimal {
    var doubleValue:Double {
        return NSDecimalNumber(decimal:self).doubleValue
    }
}

// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue
Run Code Online (Sandbox Code Playgroud)

  • 投票认为这是 Swift 4 中接受的答案。干净,虽然不是理想的解决方案,理想情况下 Decimal 类型应该在 Swift 语言中干净地提供双重转换。 (2认同)

Pra*_* Sp 5

Swift 4中有效的解决方案

let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)
Run Code Online (Sandbox Code Playgroud)

编辑:NSDecimalNumber/NSNumber

let double = 3.14
let decimal = Decimal(double)
if let doubleFromDecimal = Double(decimal.description){
    print(doubleFromDecimal)
}
Run Code Online (Sandbox Code Playgroud)


Raf*_*fAl 5

斯威夫特 5

let doubleValue = Double(truncating: decimalValue as NSNumber)
Run Code Online (Sandbox Code Playgroud)

  • 确实它有效......但你仍然使用第三种类型,这里是`NSNumber`。这篇文章背后的整个想法是代码的效率和清晰度问题。关键是,如果不使用 hack(通过 `NSNumber`、`NSDecimalNumber`、`String`、指针或其他东西......)这个问题比开发更具修辞性……而缺少的方法在 Swift 5 中仍然缺失。 (2认同)

use*_*434 3

Decimal在 Swift 3 中不是NSDecimalNumber. 这是NSDecimal完全不同的类型。

NSDecimalNumber您应该像以前一样继续使用。

  • 实际上,“Decimal”对应于“NSDecimalNumber”:“Foundation 框架的 Swift 覆盖提供了 Decimal 结构,它桥接到 NSDecimalNumber 类。Decimal 值类型提供与 NSDecimalNumber 引用类型相同的功能,并且两者可以在与 Objective-C API 交互的 Swift 代码中互换使用 https://developer.apple.com/reference/foundation/nsdecimalnumber (4认同)
  • 是的,我没有声称确实如此。我只是说你关于“Decimal”对应于“NSDecimal”的假设是错误的。 (2认同)
  • 尽管文档说 Decimal 桥接到 NSDecimalNumber,但根据我的经验,目前最安全的是坚持使用 NSDecimalNumber,并等待库稳定(尝试转换为 Decimal,它比我预期的更混乱,加上生成的代码坠毁)。 (2认同)