Int-to-UInt (e viceversa) bit casting in Swift

Sto cercando un modo diretto per eseguire il cast dei bit dei valori di un Int a UInt e viceversa. Ad esempio (utilizzando gli interi a 8 bit per semplicità) voglio get quanto segue:

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

All'inizio sono uscito con la seguente soluzione:

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

Ma Apple nella documentazione "unsafeBitCast ()" afferma quanto segue:

.. Attenzione :: Rompe le garanzie del sistema di tipo di Swift; usare con estrema cura. C'è quasi sempre un modo migliore per fare qualsiasi cosa.

Qualcuno ha il modo migliore?

Solutions Collecting From Web of "Int-to-UInt (e viceversa) bit casting in Swift"

Tu puoi fare:

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

Esistono molti inizializzatori simili:

 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) } 

Ho preso la via algebra. Il test è stato un problema perché è facile get un overflow con la forte digitazione che interrompe l'esecuzione, PlayGround ha restituito un valore negativo dalla function toUInt, ha continuato a bloccarsi o ha dato errori divertenti eseguendo un doppio casting (ho aperto un bug report). Comunque questo è quello che ho finito con:

 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 } 

Li ho testati con tutti i valori estremi (UInt.min, UInt.max, Int.min, Int.max) e quando XCode non impazzisce sembra funzionare, ma sembra eccessivamente complicato. È abbastanza bizzarro il bit casting da UInt a Int che può essere ottenuto semplicemente con la properties; hashvalue come in:

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

Ma ovviamente non è garantito che funzioni sempre (dovrebbe, ma preferirei non correre il rischio).

Qualsiasi altra idea sarà apprezzata.

numberscCast(...) è ciò che stai cercando. È un insieme di funzioni generics che converte da e verso diversi tipi di numbers. Scegli l'implementazione corretta in base ai tipi del suo argomento e al tipo di return.