Ios Swift 3中的十进制到双精度转换
我正在将一个项目从Swift 2.2迁移到Swift 3,并在可能的情况下尝试摆脱旧的Cocoa数据类型 我的问题是:将Ios Swift 3中的十进制到双精度转换,ios,swift,migration,type-conversion,swift3,Ios,Swift,Migration,Type Conversion,Swift3,我正在将一个项目从Swift 2.2迁移到Swift 3,并在可能的情况下尝试摆脱旧的Cocoa数据类型 我的问题是:将NSDecimalNumber迁移到Decimal 我曾经在Swift 2.2中通过NSDecimalNumber到Double双向桥接: let double = 3.14 let decimalNumber = NSDecimalNumber(value: double) let doubleFromDecimal = decimalNumber.doubleValue
NSDecimalNumber
迁移到Decimal
我曾经在Swift 2.2中通过NSDecimalNumber
到Double
双向桥接:
let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)
let doubleFromDecimal = decimalNumber.doubleValue
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = ???
现在,切换到Swift 3:
let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)
let doubleFromDecimal = decimalNumber.doubleValue
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = ???
decimal.doubleValue
不存在,也不存在Double(decimal)
,甚至不存在作为Double的十进制
。。。
我想到的唯一一个技巧是:
let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue
但是,如果试图摆脱NSDecimalNumber
,而不得不偶尔使用它,那将是完全愚蠢的
嗯,要么我错过了一些明显的东西,请原谅我浪费了你的时间,要么我认为有一个漏洞需要解决
提前感谢你的帮助
编辑:在Swift 4上没有更多关于该主题的内容
编辑:Swift 3中的Swift 5
十进制
主题没有更多内容。这是完全不同的类型
您应该像以前一样继续使用
NSDecimalNumber
。NSDecimalNumber
和Decimal
是桥接的
对基础框架的快速覆盖提供小数 结构,它连接到NSDecimalNumber类。小数点 值类型提供与NSDecimalNumber相同的功能 引用类型,两者可在Swift代码中互换使用 它与Objective-CAPI交互。这种行为类似于 Swift将标准字符串、数字和集合类型桥接到其 对应的基础类。 但与其他一些桥接类型一样,某些元素缺失
要恢复功能,您可以编写扩展:extension Decimal {
var doubleValue:Double {
return NSDecimalNumber(decimal:self).doubleValue
}
}
// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue
在Swift 3中工作的另一个解决方案是将
Decimal
转换为NSNumber
,并从中创建Double
let someDouble = Double(someDecimal as NSNumber)
从Swift 4.2开始,您需要:
let someDouble = Double(truncating: someDecimal as NSNumber)
在Swift 4中工作的解决方案
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)
您应该使用
as
操作符将Swift类型转换为其桥接的基础Objective-C类型。所以只要像这样使用
let p = Decimal(1)
let q = (p as NSDecimalNumber).doubleValue
在Swift 4中,decimalnumber
是NSDecimalNumber
。这是苹果官方文档在Xcode 10中的引用
重要
对基础框架的快速覆盖提供了<代码>十进制< /代码>
结构,它连接到
NSDecimalNumber
类。更多
有关值类型的信息,请参阅中的使用Cocoa框架
结合Cocoa和Objective-C使用Swift(Swift 4.1)
不再有NSDecimal
。
Swift 3中有令人困惑的NSDecimal
类型,但它似乎是一个bug。
没有更多的困惑
注
我知道OP对Swift 4不感兴趣,但我添加了这个答案,因为只提到(过时的)Swift 3让我感到困惑。Swift 5
在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)
}
}
双分机{
@Inlineable init(uOther:十进制){
如果其他,则长度==0{
self.init(other.\u isNegative==1?Double.nan:0)
返回
}
变量d:Double=0.0
对于idx in(0..对于swift 5,函数为
let doubleValue = Double(truncating: decimalValue as NSNumber)
下面的示例显示了浮点数
let decimalValue: Decimal = 3.14159
let doubleValue = Double(truncating: decimalValue as NSNumber)
print(String(format: "%.3f", doubleValue)) // 3.142
print(String(format: "%.4f", doubleValue)) // 3.1416
print(String(format: "%.5f", doubleValue)) // 3.14159
print(String(format: "%.6f", doubleValue)) // 3.141590
print(String(format: "%.7f", doubleValue)) // 3.1415900
实际上,十进制< /C> >对应于银行代码> NSDECIMALNOTENS/<代码>:<代码>对基础框架的SWIFT覆盖提供了小数结构,它与NSCDIMALNATE类桥接。十进制值类型提供与NSDECIMALNATE引用类型相同的功能,并且两者可以在SWIFT代码中互换使用。它与Objective-C API
@AlexanderMomchliov交互,只是它没有可用的NSDecimalNumber
方法,所以为了使用它们,你仍然需要将DecimalNumber
转换为NSDecimalNumber
。来源:只是在操场上检查了一下。是的,我没有声明。我只是说你的假设是DE> >十进制< /代码>对应于<代码> NSDecimal <代码>,是错误的。@ AlexanderMomchliov,但它是<代码> NSDecimal <代码>,只比较SWIFT 3的生成标题中的<代码>十进制< /代码>在基础C代码中的<代码> NSDecimal > /代码>。只是因为SWIFT桥<代码>十进制< /代码>旧基础代码变为<代码> NSDECIMALALNOT/<代码>导入时,并不意味着decimalnumber
变为NSDecimalNumber
。尽管文档中说decimalnumber连接到NSDecimalNumber,但根据我的经验,现在最好还是坚持使用NSDecimalNumber,等待库稳定下来(尝试转换为十进制,结果比我预期的更混乱,加上生成的代码崩溃了)。let c=Double(截断:a为NSNumber)
在Swift中4@vikingosegundo这就是Swift 4。在Swift 3中,您不需要使用截断
。是的,但您仍然必须转换为第三种类型…您不能只使用双精度
和十进制
,您需要使用NSDecimalNumber
或NSNumber
。即使是这样,问题仍然是一样的被扩展名隐藏。你仍然必须使用第三种类型,而不是只有'Double'和Decimal
…投票决定这是Swift 4中被接受的答案。干净,虽然不是理想的解决方案,但理想的是Decimal类型应该在Swift语言中提供干净的双重转换。是的,2018年仍然是一个多么糟糕的人…我是他唯一的原因确定是否移到十进制是所有的数学运算(包括文字转换,如myDecimal+1
)和比较,这比使用NSDecimalNumberYes要简单得多