Why there is a overflow with Swift language when assign a 8 bits binary value to a var of Int8 type?
While I am not experienced with Swift, I can safely assume that the binary literal does not represent the binary representation, but only the value. So 0b11111111 will still be 255. If you want -128, you should use -0b10000000.
Swift sign extension with variable number of bits
You can use Int8(bitPattern:)
to convert the given unsigned
value to a signed value with the same binary representation,
then sign extend by converting to Int16
, make unsigned again, and finally truncate
to the given number of bits:
func signExtend(val: UInt8, numBits: Int) -> UInt16 {
// Sign extend to unsigned 16-bit:
var extended = UInt16(bitPattern: Int16(Int8(bitPattern: val)))
// Truncate to given number of bits:
if numBits < 16 {
extended = extended & ((1 << numBits) - 1)
}
return extended
}
Example:
for i in 1...16 {
let x = signExtend(val: 200, numBits: i)
print(String(format: "%2d %04X", i, x))
}
Output:
1 0000
2 0000
3 0000
4 0008
5 0008
6 0008
7 0048
8 00C8
9 01C8
10 03C8
11 07C8
12 0FC8
13 1FC8
14 3FC8
15 7FC8
16 FFC8
Integer literal overflows when stored into 'Int'
UInt32(0x8BC34AFF)
creates a UInt32
by calling an initializer. The UInt32
initializer you are calling is:
init(_ v: Int)
The problem is that on a 32-bit device (iPhone5 and earlier), type Int
is 32-bits. So, the constant you are passing 0x8BC34AFF
overflows the Int
that you are passing to the initializer of UInt32
.
The way to have this work on both 32-bit and 64-bit devices is to cast the integer literal to the type:
let primary = 0x8BC34AFF as UInt32
Alternatively, declare the variable to be UInt32
and just assign the constant:
let primary:UInt32 = 0x8BC34AFF
Reading Binary File Piecemeal and Converting to Integers With Memory Efficiency
You don't show your code that actually reads from your file, so it's a bit hard to be sure what's going on.
From the code you did show we can tell you're using a FileHandle, which allows random access to a file and reading arbitrary-sized blocks of data.
Assuming you're doing that part right and reading 10 million bytes at a time, your problem may be the way iOS and Mac OS handle memory. For some things, the OS puts no-longer-used memory blocks into an "autorelease pool", which gets freed when your code returns and the event loop gets serviced. If you're churning through multiple gigabytes of file data synchronously, it might not get a chance to release the memory before the next pass.
(Explaining Mac OS/iOS memory management in enough detail to cover autoreleasing would be pretty involved. If you're interested, I suggest you look up Apple manual reference counting and automatic reference counting, a.k.a ARC, and look for results that explain what goes on "under the covers".)
Try putting the code that reads 10 million bytes of data into the closure of an autoreleasePool()
statement. That will cause any autoreleased memory to actually get released. Something like the pseudo-code below:
while (more data) {
autoreleasepool {
// read a 10 million byte block of data
// process that block
}
}
Swift - Convert UInt8 byte to array of bits
Here's a basic function to get a Bit
array from a byte:
func bits(fromByte byte: UInt8) -> [Bit] {
var byte = byte
var bits = [Bit](repeating: .zero, count: 8)
for i in 0..<8 {
let currentBit = byte & 0x01
if currentBit != 0 {
bits[i] = .one
}
byte >>= 1
}
return bits
}
Here, Bit
is a custom enum type that I have defined as follows:
enum Bit: UInt8, CustomStringConvertible {
case zero, one
var description: String {
switch self {
case .one:
return "1"
case .zero:
return "0"
}
}
}
With this setup, the output of the following code:
let byte: UInt8 = 0x1f
print(bits(fromByte: byte))
would be:
[1, 1, 1, 1, 1, 0, 0, 0]
how to use signed hexadecimal literals in swift?
There's a special initializer for just this case:
let x = Int32(bitPattern: 0x80000001)
print(x) // -2147483647
Related Topics
How to Save a Custom Class as an Attribute of a Coredata Entity in Swift 3
Images Inaccessible from Asset Catalog in a Swiftui Framework
Cannot Invoke Initializer for Type 'Sqlite3_Destructor_Type'
Count the Number of Lines in a Swift String
Why Use Float(Arc4Random())/0Xffffffff Instead of Drand()
Perform Migration by Adding List() and Another Model Class
Diffrence Between Function and Generic Function in Swift
Why Does My @Lazy Property Crash, But If I Make It Non Lazy It Works
Swiftui: Localizedstringkey with Indices
How to Detect the 2D Images Using Arkit and Realitykit
If-Let Any to Rawrepresentable<String>
Saving Dictionary into Nsuserdefaults
Why Doesn't Swift Force My Designated Initializer to Call Super
How to Capitalize First Word in Every Sentence with Swift
Realitykit - How to Add a Video Material to a Modelentity
Obtain Nsurl from Uiimagepickercontroller