Int à UInt (et vice versa) de diffusion de bits dans Swift

Je suis à la search d'un moyen direct de muter les valeurs de bits d'un Int vers UInt et vice versa. Par exemple (en utilisant les entiers de 8 bits pour plus de simplicité), je veux réaliser ce qui suit:

let unsigned: UInt8 = toUInt8(-1) // unsigned is 255 or 0xff let signed: Int8 = toInt8(0xff) // signed is -1 

Au début, je suis sorti avec la solution suivante:

 let unsigned = unsafeBitCast(Int8(-1), UInt8.self) let signed = unsafeBitCast(UInt8(0xff), Int8.self) 

Mais Apple dans la documentation "unsafeBitCast ()" indique ce qui suit:

.. Attention :: Brise les garanties du système de type de Swift; utiliser avec un soin extrême. Il y a presque toujours une meilleure façon de faire quelque chose.

Est-ce que quelqu'un a le meilleur moyen?

    Tu peux faire:

     let unsigned = UInt8(bitPattern: Int8(-1)) // -> 255 let signed = Int8(bitPattern: UInt8(0xff)) // -> -1 

    De nombreux initialiseurs similaires existent:

     extension Int8 { init(_ v: UInt8) init(_ v: UInt16) init(truncatingBitPattern: UInt16) init(_ v: Int16) init(truncatingBitPattern: Int16) init(_ v: UInt32) init(truncatingBitPattern: UInt32) init(_ v: Int32) init(truncatingBitPattern: Int32) init(_ v: UInt64) init(truncatingBitPattern: UInt64) init(_ v: Int64) init(truncatingBitPattern: Int64) init(_ v: UInt) init(truncatingBitPattern: UInt) init(_ v: Int) init(truncatingBitPattern: Int) init(bitPattern: UInt8) } 

    J'ai pris la route de l'algèbre. Le test a été pénible car il est facile d'get un débordement avec la frappe forte brisant l'exécution, PlayGround a renvoyé une valeur négative de la fonction toUInt, il a continué à s'écraser ou a donné des erreurs amusantes en double casting (J'ai ouvert un rapport de bug). En tout cas c'est ce que j'ai fini par:

     func toUint(signed: Int) -> UInt { let unsigned = signed >= 0 ? UInt(signed) : UInt(signed - Int.min) + UInt(Int.max) + 1 return unsigned } func toInt(unsigned: UInt) -> Int { let signed = (unsigned <= UInt(Int.max)) ? Int(unsigned) : Int(unsigned - UInt(Int.max) - 1) + Int.min return signed } 

    Je les ai testés avec toutes les valeurs extrêmes (UInt.min, UInt.max, Int.min, Int.max) et quand XCode ne devient pas fou il semble fonctionner, mais il semble trop compliqué. Assez bizarre le casting UInt à Int peut être simplement réalisé avec la propriété hashvalue comme dans:

     signed = UInt.max.hashValue // signed is -1 

    Mais évidemment, il n'est pas garanti de toujours travailler (il le devrait, mais je préfère ne pas prendre le risque).

    Toute autre idée sera appréciée.

    numericCast(...) est ce que vous cherchez. C'est un set de fonctions generics qui convertit de et vers différents types de nombres. Il choisit l'implémentation correcte en fonction des types de son argument et du type de return.