Swift 4 - Double 到 big-endian 的高效转换
Swift 4 - efficient conversion of Double to big-endian
我需要将 Double 格式转换为大端格式,以便使用石油行业二进制文件标准将其写入文件,该标准最初是在 1970 年代为 IBM 半英寸 9 磁道磁带定义的!
我需要非常高效的 Swift 4 代码,因为这个转换在两个嵌套循环中进行,将执行超过 100,000 次。
您可以创建一个包含大端表示的 UInt64
Double
和
let value = 1.0
var n = value.bitPattern.bigEndian
为了将其写入文件,您可能需要将其转换
到 Data
:
let data = Data(buffer: UnsafeBufferPointer(start: &n, count: 1))
print(data as NSData) // <3ff00000 00000000>
如果将许多连续的浮点值写入文件
那么创建一个 [UInt64]
数组会更有效
使用大端表示并将其转换为 Data
,
例如
let values = [1.0, 2.0, 3.0, 4.0]
let array = values.map { [=12=].bitPattern.bigEndian }
let data = array.withUnsafeBufferPointer { Data(buffer: [=12=]) }
(以上所有内容均使用 Swift 3 和 4 进行编译。)
我成功实现了 Martin 的数组建议。我决定我应该使用一些 "interesting" 测试值,一件事导致另一件事!这是我的测试游乐场。希望大家感兴趣:
//: Playground - noun: a place where people can play
import UIKit
func convert(doubleArray: [Double]) {
let littleEndianArray = doubleArray.map { [=10=].bitPattern}
var data = littleEndianArray.withUnsafeBufferPointer { Data(buffer: [=10=]) }
print("Little-endian : ", data as NSData)
// Convert and display the big-endian bytes
let bigEndianArray = doubleArray.map { [=10=].bitPattern.bigEndian }
data = bigEndianArray.withUnsafeBufferPointer { Data(buffer: [=10=]) }
print("Big-endian : ", data as NSData)
}
// Values below are from:
// https://en.wikipedia.org/wiki/Double-precision_floating-point_format
let nan = Double.nan
let plusInfinity = +1.0 / 0.0
let maxDouble = +1.7976931348623157E308
let smallestNumberGreaterThanOne = +1.0000000000000002
let plusOne = +1.0
let maxSubnormalPositiveDouble = +2.2250738585072009E-308
let minSubnormalPositiveDouble = +4.9E-324
let plusZero = +0.0
let minusZero = -0.0
let maxSubnormalNegativeDouble = -4.9E-324
let minSubnormalNegativeDouble = -2.2250738585072009E-308
let minusOne = -1.0
let largestNumberLessThanOne = -1.0000000000000002
let minDouble = -1.7976931348623157E308
let minusInfinity = -1.0 / 0.0
let smallestNumber = "+1.0000000000000002"
let largestNumber = "-1.0000000000000002"
print("\n\nPrint little-endian and big-endian Doubles")
print("\n\nDisplay: NaN and +0.0 to +1.0")
print(" Min. Subnormal Max. Subnormal")
print(" Not a Number Plus Zero Positive Double Positive Double Plus One")
print(String(format: "Decimal : NaN %+8.6e %+8.6e %+8.6e %+8.6e", plusZero, minSubnormalPositiveDouble, maxSubnormalPositiveDouble, plusOne))
var doubleArray = [nan, plusZero, minSubnormalPositiveDouble, maxSubnormalPositiveDouble, plusOne]
convert(doubleArray: doubleArray)
print("\n\nDisplay: +1.0 to +Infinity")
print(" Smallest Number ")
print(" Plus One Greater Than 1.0 Max. Double +Infinity")
print(String(format: "Decimal : %+8.6e \(smallestNumber) %+8.6e%+8.6e", plusOne, maxDouble, plusInfinity))
doubleArray = [plusOne, smallestNumberGreaterThanOne, maxDouble, plusInfinity]
convert(doubleArray: doubleArray)
print("\n\nDisplay: NaN and -0.0 to -1.0")
print(" Min. Subnormal Max. Subnormal")
print(" Not a Number Minus Zero Negative Double Negative Double Minus One")
print(String(format: "Decimal : NaN %+8.6e %+8.6e %+8.6e %+8.6e", minusZero, maxSubnormalNegativeDouble, minSubnormalNegativeDouble, minusOne))
doubleArray = [nan, minusZero, maxSubnormalNegativeDouble, minSubnormalNegativeDouble, minusOne]
convert(doubleArray: doubleArray)
print("\n\nDisplay: -1.0 to -Infinity")
print(" Smallest Number ")
print(" Minus One Less Than -1.0 Min. Double -Infinity")
print(String(format: "Decimal : %+8.6e \(largestNumber) %+8.6e%+8.6e", minusOne, minDouble, minusInfinity))
doubleArray = [minusOne, largestNumberLessThanOne, minDouble, minusInfinity]
convert(doubleArray: doubleArray)
我需要将 Double 格式转换为大端格式,以便使用石油行业二进制文件标准将其写入文件,该标准最初是在 1970 年代为 IBM 半英寸 9 磁道磁带定义的!
我需要非常高效的 Swift 4 代码,因为这个转换在两个嵌套循环中进行,将执行超过 100,000 次。
您可以创建一个包含大端表示的 UInt64
Double
和
let value = 1.0
var n = value.bitPattern.bigEndian
为了将其写入文件,您可能需要将其转换
到 Data
:
let data = Data(buffer: UnsafeBufferPointer(start: &n, count: 1))
print(data as NSData) // <3ff00000 00000000>
如果将许多连续的浮点值写入文件
那么创建一个 [UInt64]
数组会更有效
使用大端表示并将其转换为 Data
,
例如
let values = [1.0, 2.0, 3.0, 4.0]
let array = values.map { [=12=].bitPattern.bigEndian }
let data = array.withUnsafeBufferPointer { Data(buffer: [=12=]) }
(以上所有内容均使用 Swift 3 和 4 进行编译。)
我成功实现了 Martin 的数组建议。我决定我应该使用一些 "interesting" 测试值,一件事导致另一件事!这是我的测试游乐场。希望大家感兴趣:
//: Playground - noun: a place where people can play
import UIKit
func convert(doubleArray: [Double]) {
let littleEndianArray = doubleArray.map { [=10=].bitPattern}
var data = littleEndianArray.withUnsafeBufferPointer { Data(buffer: [=10=]) }
print("Little-endian : ", data as NSData)
// Convert and display the big-endian bytes
let bigEndianArray = doubleArray.map { [=10=].bitPattern.bigEndian }
data = bigEndianArray.withUnsafeBufferPointer { Data(buffer: [=10=]) }
print("Big-endian : ", data as NSData)
}
// Values below are from:
// https://en.wikipedia.org/wiki/Double-precision_floating-point_format
let nan = Double.nan
let plusInfinity = +1.0 / 0.0
let maxDouble = +1.7976931348623157E308
let smallestNumberGreaterThanOne = +1.0000000000000002
let plusOne = +1.0
let maxSubnormalPositiveDouble = +2.2250738585072009E-308
let minSubnormalPositiveDouble = +4.9E-324
let plusZero = +0.0
let minusZero = -0.0
let maxSubnormalNegativeDouble = -4.9E-324
let minSubnormalNegativeDouble = -2.2250738585072009E-308
let minusOne = -1.0
let largestNumberLessThanOne = -1.0000000000000002
let minDouble = -1.7976931348623157E308
let minusInfinity = -1.0 / 0.0
let smallestNumber = "+1.0000000000000002"
let largestNumber = "-1.0000000000000002"
print("\n\nPrint little-endian and big-endian Doubles")
print("\n\nDisplay: NaN and +0.0 to +1.0")
print(" Min. Subnormal Max. Subnormal")
print(" Not a Number Plus Zero Positive Double Positive Double Plus One")
print(String(format: "Decimal : NaN %+8.6e %+8.6e %+8.6e %+8.6e", plusZero, minSubnormalPositiveDouble, maxSubnormalPositiveDouble, plusOne))
var doubleArray = [nan, plusZero, minSubnormalPositiveDouble, maxSubnormalPositiveDouble, plusOne]
convert(doubleArray: doubleArray)
print("\n\nDisplay: +1.0 to +Infinity")
print(" Smallest Number ")
print(" Plus One Greater Than 1.0 Max. Double +Infinity")
print(String(format: "Decimal : %+8.6e \(smallestNumber) %+8.6e%+8.6e", plusOne, maxDouble, plusInfinity))
doubleArray = [plusOne, smallestNumberGreaterThanOne, maxDouble, plusInfinity]
convert(doubleArray: doubleArray)
print("\n\nDisplay: NaN and -0.0 to -1.0")
print(" Min. Subnormal Max. Subnormal")
print(" Not a Number Minus Zero Negative Double Negative Double Minus One")
print(String(format: "Decimal : NaN %+8.6e %+8.6e %+8.6e %+8.6e", minusZero, maxSubnormalNegativeDouble, minSubnormalNegativeDouble, minusOne))
doubleArray = [nan, minusZero, maxSubnormalNegativeDouble, minSubnormalNegativeDouble, minusOne]
convert(doubleArray: doubleArray)
print("\n\nDisplay: -1.0 to -Infinity")
print(" Smallest Number ")
print(" Minus One Less Than -1.0 Min. Double -Infinity")
print(String(format: "Decimal : %+8.6e \(largestNumber) %+8.6e%+8.6e", minusOne, minDouble, minusInfinity))
doubleArray = [minusOne, largestNumberLessThanOne, minDouble, minusInfinity]
convert(doubleArray: doubleArray)