Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift 3中的十进制到双精度转换_Ios_Swift_Migration_Type Conversion_Swift3 - Fatal编程技术网

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

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

我正在将一个项目从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
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要简单得多