As you guys know, I always loved playing with binary stuff, and one of the frustrating thing in ActionScript has always been the lack of more granular data types. In ActionScript 3, whatever type you use, it will either occupy 64 or 32 bits in memory, even for a simple boolean. Not super optimized. So if you were to work with a byte (which is 8-bit), the smallest data type you could use to store it would be an int (32-bit signed integer) or a uint (32-bit unsigned integer).

So what’s up with overflowing? Well, I first encountered that problem when working on a Intel8080 CPU emulator in AS3. Every CPU register for the Intel8080 is a 8-bit register. Because there is no byte type equivalent (8-bit integer) in AS3, as I said earlier, you are left with int or uint, therefore you are using 32-bit for each 8-bit register, meaning that no error will be triggered if you try to store more than 8-bits on the register. This is what overflow means, when you try to store more data than what the type can hold.

So in AS3, I ended up spending hours trying to understand what was wrong. The code below illustrates the idea:

// 255 is the max value a unsigned byte can hold
// but because I am using a uint, it will overflow
var myRegister: uint = 255;

// if I add 1 to it
myRegister += 1;

// I end up with 256 which is 100000000 in binary
// outputs: 100000000
trace ( myRegister.toString ( 2 ) );

Because a uint can hold 32 bits, by adding I end up with 256, represented as 9 bits (100000000). Makes sense right?

Makes absolute sense, but in the context of a register that is never supposed to go higher than 255, it is a problem. After hours of debugging, I thought that masking the registers to only preserve the rightmost 8 bits could help. That was indeed the problem, but it took me forever to discover that. I recall my buddy Claus had the same issue when working on FC64 (a Commodore 64 emulator in AS3). So I ended up masking pretty much all operations on registers. Here is an example of how it works:

// 255 is the max value a unsigned byte can hold
// but because I am using a uint, it will overflow
var myRegister: uint = 255;

// if I add 1 to it
myRegister += 1;

// I end up with 256 which is 100000000 in binary
// outputs: 100000000
trace ( myRegister.toString ( 2 ) );

// we preserve only the rightmost 8 bits
myRegister &= 0xFF;

// outputs: 0
trace ( myRegister.toString ( 2 ) );

In the CPU emulator, it looked like this, see the first line:

protected function PerformCompSub(inValue:int):void
{
var value:int = (A - inValue) & 0xFF;
CARRY = int(((value >= A) && (inValue)));
HALFCARRY = ((A ^ inValue ^ value) & 0x10);
ZERO = int((value == 0));
SIGN = (value & 128);
}

So what is great about Swift? Well, first, Swift provides a more granular data type, like Int8 or UInt8:

var unsignedByte: UInt8 = UInt8.max
var signedByte: Int8 = Int8.max

The first advantage, is that these two variables will only occupy 8 bit in memory, so only what’s required. That is a good first optimization. Second benefit, Swift leverages type inference, so you don’t need to explicitly specify types. If you don’t, like with the code below, the compiler will automatically infer the most efficient type, in that case (UInt8 and Int8):

var unsignedByte = UInt8.max
var signedByte = Int8.max

Third benefit, if you try to add 1 to this variable, because you are already occupying 8 bits, adding 1 will cause a compile time error, so the code below:

var unsignedByte = UInt8.max
unsignedByte += 1

Will cause the following compiler error:

Arithmetic operation '255 + 1' (on type 'UInt8') results in an overflow

Pretty cool right? In AS3, it would overflow silently and that can be sneaky. At runtime, same safety, it would trigger a runtime exception and that would have saved me hours of debugging in AS3. But in some scenarios you may have bigger values but still want the overflowing to happen silently and perform the masking operation implicitly. I can do that in Swift by using the &+ operator:

// our unsigned byte set to 255
var unsignedByte = UInt8.max

// we add 1 to 255, using the &+ operator instead of + to allow overflow
unsignedByte = unsignedByte &+ 1

// outputs: 0
println(unsignedByte)

More granular data types and advanced operators are very welcome in Swift, I will probably port the Intel8080 emulator in Swift and talk about it here. In the mean time, you can use the ampersand (&) before all common operators: +, -, /, * to allow overflowing and underflowing. For more details about this operator and this topic, check the Advanced operator section in the Swift documentation.