ios Swift 3 中的十进制到双精度转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39890795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Decimal to Double conversion in Swift 3
提问by Zaphod
I'm migrating a project from Swift 2.2to Swift 3, and I'm trying to get rid of old Cocoa data types when possible.
我正在将一个项目从Swift 2.2迁移到Swift 3,并且我试图在可能的情况下摆脱旧的 Cocoa 数据类型。
My problem is here: migrating NSDecimalNumber
to Decimal
.
我的问题在这里:迁移NSDecimalNumber
到Decimal
.
I used to bridge NSDecimalNumber
to Double
both ways in Swift 2.2:
我用来桥接NSDecimalNumber
以Double
这两种方式雨燕2.2:
let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)
let doubleFromDecimal = decimalNumber.doubleValue
Now, switching to Swift 3:
现在,切换到Swift 3:
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = ???
decimal.doubleValue
does not exist, nor Double(decimal)
, not even decimal as Double
...
The only hack I come up with is:
decimal.doubleValue
不存在,也不存在,Double(decimal)
甚至不存在decimal as Double
......我想出的唯一黑客是:
let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue
But that would be completely stupid to try to get rid of NSDecimalNumber
, and have to use it once in a while...
但是试图摆脱它是完全愚蠢的NSDecimalNumber
,并且不得不偶尔使用它......
Well, either I missed something obvious, and I beg your pardon for wasting your time, or there's a loophole needed to be addressed, in my opinion...
好吧,要么我错过了一些明显的东西,请原谅浪费你的时间,要么有一个漏洞需要解决,在我看来......
Thanks in advance for your help.
在此先感谢您的帮助。
Edit: Nothing more on the subject on Swift 4.
编辑:没有更多关于Swift 4的主题。
Edit: Nothing more on the subject on Swift 5.
编辑:没有更多关于Swift 5的主题。
回答by rmaddy
Another solution that works in Swift 3 is to cast the Decimal
to NSNumber
and create the Double
from that.
另一个适用于 Swift 3 的解决方案是投射Decimal
toNSNumber
并Double
从中创建。
let someDouble = Double(someDecimal as NSNumber)
As of Swift 4.2 you need:
从 Swift 4.2 开始,您需要:
let someDouble = Double(truncating: someDecimal as NSNumber)
回答by sketchyTech
NSDecimalNumber
and Decimal
are bridged
NSDecimalNumber
并被Decimal
桥接
The Swift overlay to the Foundation framework provides the Decimal structure, which bridges to the NSDecimalNumber class. The Decimal value type offers the same functionality as the NSDecimalNumber reference type, and the two can be used interchangeably in Swift code that interacts with Objective-C APIs. This behavior is similar to how Swift bridges standard string, numeric, and collection types to their corresponding Foundation classes. Apple Docs
Swift 覆盖到 Foundation 框架提供了 Decimal 结构,它连接到 NSDecimalNumber 类。Decimal 值类型提供与 NSDecimalNumber 引用类型相同的功能,并且两者可以在与 Objective-C API 交互的 Swift 代码中互换使用。这种行为类似于 Swift 将标准字符串、数字和集合类型桥接到它们相应的 Foundation 类的方式。苹果文档
but as with some other bridged types certain elements are missing.
但与其他一些桥接类型一样,缺少某些元素。
To regain the functionality you could write an extension:
要重新获得功能,您可以编写扩展程序:
extension Decimal {
var doubleValue:Double {
return NSDecimalNumber(decimal:self).doubleValue
}
}
// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue
回答by Pranavan Sp
Solution that works in Swift 4
适用于Swift 4 的解决方案
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)
Edit:Without NSDecimalNumber
/NSNumber
编辑:没有NSDecimalNumber
/NSNumber
let double = 3.14
let decimal = Decimal(double)
if let doubleFromDecimal = Double(decimal.description){
print(doubleFromDecimal)
}
回答by user28434
Decimal
in Swift 3 is not NSDecimalNumber
. It's NSDecimal
, completely different type.
Decimal
在 Swift 3 中不是NSDecimalNumber
。它NSDecimal
,完全不同的类型。
You should just keep using NSDecimalNumber
as you did before.
你应该NSDecimalNumber
像以前一样继续使用。
回答by Eonil
You are supposed to use as
operator to cast a Swift type to its bridgedunderlying Objective-C type. So just use as
like this.
您应该使用as
运算符将 Swift 类型转换为其桥接的底层 Objective-C 类型。所以就这样使用as
。
let p = Decimal(1)
let q = (p as NSDecimalNumber).doubleValue
In Swift 4, Decimal
isNSDecimalNumber
. Here's citation from Apple's official documentation in Xcode 10.
在 Swift 4 中,Decimal
是NSDecimalNumber
. 这是 Xcode 10 中 Apple 官方文档的引用。
Important
The Swift overlay to the Foundation framework provides the
Decimal
structure, which bridges to theNSDecimalNumber
class. For more information about value types, see Working with Cocoa Frameworks in Using Swift with Cocoa and Objective-C (Swift 4.1).
重要的
Swift 覆盖到 Foundation 框架提供了
Decimal
连接到NSDecimalNumber
类的结构。有关值类型的更多信息,请参阅使用 Swift 与 Cocoa 和 Objective-C (Swift 4.1) 中的使用 Cocoa 框架。
There's no NSDecimal
anymore.
There was confusing NSDecimal
type in Swift 3, but it seems to be a bug.
No more confusion.
没有NSDecimal
了。NSDecimal
Swift 3 中有令人困惑的类型,但这似乎是一个错误。没有更多的困惑。
Note
笔记
I see the OP is not interested in Swift 4, but I added this answer because mentioning only about (outdated) Swift 3 made me confused.
我看到 OP 对 Swift 4 不感兴趣,但我添加了这个答案,因为只提到(过时的)Swift 3 让我感到困惑。
回答by RaffAl
Swift 5
斯威夫特 5
let doubleValue = Double(truncating: decimalValue as NSNumber)
回答by Eugene Dudnyk
In Swift open source, the implementationis actually done in Decimal.swift
, but it is private. You can re-use the code from there.
在 Swift 开源中,实现实际上是在 中完成的Decimal.swift
,但它是私有的。您可以从那里重新使用代码。
extension Double {
@inlinable init(_ other: Decimal) {
if other._length == 0 {
self.init(other._isNegative == 1 ? Double.nan : 0)
return
}
var d: Double = 0.0
for idx in (0..<min(other._length, 8)).reversed() {
var m: Double
switch idx {
case 0: m = Double(other._mantissa.0)
break
case 1: m = Double(other._mantissa.1)
break
case 2: m = Double(other._mantissa.2)
break
case 3: m = Double(other._mantissa.3)
break
case 4: m = Double(other._mantissa.4)
break
case 5: m = Double(other._mantissa.5)
break
case 6: m = Double(other._mantissa.6)
break
case 7: m = Double(other._mantissa.7)
break
default: break
}
d = d * 65536 + m
}
if other._exponent < 0 {
for _ in other._exponent..<0 {
d /= 10.0
}
} else {
for _ in 0..<other._exponent {
d *= 10.0
}
}
self.init(other._isNegative != 0 ? -d : d)
}
}