tetu式

ゲームと音楽・作曲の自己満足と悩みどころの多いプログラムのブログ。

Swiftで使えるあまり見かけない演算子について その1

他のプログラム言語でもそうなのですが、どういう時に使えばいいのか分からない
演算子っていうのは多くあります。
今回は仕事上であまり見かけることのないそんな演算子の話。



オーバーフロー算術演算子
var numA: Int8 = 127
var numB: Int8 = 127

var numC = numA + numB  // エラー

print(numC)

まずはこんな例。
127 + 127 は254ですが、Int8型は-128〜127までの数字しか扱えないため、
オーバーフローが発生してエラーになります。

この内容を一応防いでくれるのがオーバーフローを許容した算術演算子
通常扱う算術演算子の前に & を付けます。

var numA: Int8 = 127
var numB: Int8 = 127

var numC = numA &+ numB

print(numC)  // -2

あれ?254じゃないの?
と思いそうですが、オーバーフローをした時、数値はループするようになってます。

var numA: Int8 = 127
var numB: Int8 = 1

var numC = numA &+ numB

print(numC)  // -128

2進数の話になりますが、00000001は1。
01111111は127です。

Int8型の場合、一番左のビットはマイナス符号を表しており、
ここだけ符号がマイナスになります。


なので10000000は-128。
一番左以外のビットは通常通りなので
10000001は-127。


本来127から繰り上がる時にオーバーフローが発生するのを許可しない場合はエラーとなりますが
01111111に1足すと10000000になるため、-128になる訳です。


また、リテラルで計算する場合、使用してる変数の型の範囲外の数字で計算する場合、
変数の型の範囲で計算するようになるため、

var numA: Int8 = 127

var numB = numA &+ 128  // エラー
print(numB)

Int8の範囲外となるリテラルで計算しようとするとエラーになります。
あくまで範囲内での計算におけるオーバーフローにだけ対応できるということに注意です。