2017-08-19 4 views
0

J'ai besoin de convertir un Double en big-endian pour l'écrire dans un fichier, en utilisant une norme de fichier binaire de l'industrie pétrolière, qui a été initialement définie pour la moitié d'IBM. pouces bandes 9 pistes dans les années 1970!Swift 4 - conversion efficace de Double en big-endian

J'ai besoin d'un code Swift 4 vraiment efficace, car cette conversion est à l'intérieur de deux boucles imbriquées et sera exécutée plus de 100 000 fois.

Répondre

1

Vous pouvez créer un UInt64 contenant la représentation big-endian du Double avec

let value = 1.0 
var n = value.bitPattern.bigEndian 

Pour écrire que dans un fichier que vous pourriez avoir besoin de le convertir à Data:

let data = Data(buffer: UnsafeBufferPointer(start: &n, count: 1)) 
print(data as NSData) // <3ff00000 00000000> 

Si de nombreuses valeurs à virgule flottante contiguë sont écrites dans le fichier , il sera plus efficace de créer un [UInt64] tableau avec les représentations big-endian et convertir en Data, par exemple

let values = [1.0, 2.0, 3.0, 4.0] 
let array = values.map { $0.bitPattern.bigEndian } 
let data = array.withUnsafeBufferPointer { Data(buffer: $0) } 

(Toutes les compiles ci-dessus avec Swift 3 et 4.)

+0

Martin R, merci pour la réponse rapide - moins de 30 minutes! Exactement ce dont j'avais besoin. J'allais ajouter que je pourrais stocker les résultats de la boucle interne dans un tableau (~ 500 à 1000 valeurs), mais vous avez anticipé mon édition! :-) Je vais mettre en œuvre votre suggestion et poster mes résultats. –

+0

J'ai implémenté avec succès la suggestion de tableau de Martin. J'ai décidé que je devais utiliser des valeurs de test «intéressantes» et une chose en entraînant une autre! –

0

Je mis en œuvre avec succès la suggestion de tableau de Martin. J'ai décidé que je devais utiliser des valeurs de test «intéressantes» et une chose en entraînant une autre! Voici mon terrain de jeu d'essai. J'espère qu'il est d'intérêt:

//: Playground - noun: a place where people can play 

import UIKit 

func convert(doubleArray: [Double]) { 
    let littleEndianArray = doubleArray.map { $0.bitPattern} 
    var data = littleEndianArray.withUnsafeBufferPointer { Data(buffer: $0) } 
    print("Little-endian : ", data as NSData) 

    // Convert and display the big-endian bytes 
    let bigEndianArray = doubleArray.map { $0.bitPattern.bigEndian } 
    data = bigEndianArray.withUnsafeBufferPointer { Data(buffer: $0) } 
    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)