コンテンツにスキップ

数値

書き方説明
int.MaxValue + 1int のあふれ
long.MaxValue + 1long のあふれ
(uint)0 - 1符号なしのあふれ
unchecked { n = n + 1; }unchecked で囲む
(byte)300型を縮める変換
(int)2.7f小数から整数への変換
byte + byte小さい型どうしの計算
-7 / 2整数の割り算
1f / 0f小数を 0 で割る
0.1 + 0.2小数の誤差

エラーは出ません。書けますし、コンパイルもされます。ただし普通の C# と違う値になる条件があります。

書き方何が起きるか
checked { n = n + 1; }C# ならあふれた時点で例外が出て止まります。ここでは何も起きず、あふれた値のまま進みます
(int)1e10fC# なら int の最小値になります。ここでは実行が止まり、続きは走りません
using UnityEngine;
using Tsukimi;
public class SilentCheckedOverflow : TsukimiBehaviour
{
void Start()
{
int n = int.MaxValue;
checked { n = n + 1; }
Debug.Log(n);
}
}
using UnityEngine;
using Tsukimi;
public class SilentFloatToIntOutOfRange : TsukimiBehaviour
{
void Start()
{
float huge = 1e10f;
Debug.Log((int)huge);
}
}

どちらも実行時の値で決まるので、コンパイル時には分かりません。checked に至っては、例外の仕組みが無いために書いても効きません。

上限を超えると下限へ、下限を下回ると上限へ回ります。例外は出ません。

using UnityEngine;
using Tsukimi;
public class NumericsIntOverflow : TsukimiBehaviour
{
void Start()
{
int max = int.MaxValue;
max = max + 1;
Debug.Log(max); // => -2147483648
int min = int.MinValue;
min = min - 1;
Debug.Log(min); // => 2147483647
}
}
using UnityEngine;
using Tsukimi;
public class NumericsLongOverflow : TsukimiBehaviour
{
void Start()
{
long n = long.MaxValue;
n = n + 1;
Debug.Log(n); // => -9223372036854775808
}
}
using UnityEngine;
using Tsukimi;
public class NumericsUnsignedWrap : TsukimiBehaviour
{
void Start()
{
uint n = 0;
n = n - 1;
Debug.Log(n); // => 4294967295
}
}

unchecked で囲んでも、囲まないときと同じ値になります。もともと検査していないためです。

using UnityEngine;
using Tsukimi;
public class NumericsUncheckedOverflow : TsukimiBehaviour
{
void Start()
{
int n = int.MaxValue;
unchecked { n = n + 1; }
Debug.Log(n); // => -2147483648
}
}
using UnityEngine;
using Tsukimi;
public class NumericsNarrowingCast : TsukimiBehaviour
{
void Start()
{
int over = 300;
Debug.Log((byte)over); // => 44
int negative = -1;
Debug.Log((byte)negative); // => 255
}
}
using UnityEngine;
using Tsukimi;
public class NumericsFloatTruncation : TsukimiBehaviour
{
void Start()
{
float positive = 2.7f;
Debug.Log((int)positive); // => 2
float negative = -2.7f;
Debug.Log((int)negative); // => -2
}
}
using UnityEngine;
using Tsukimi;
public class NumericsSmallTypeArithmetic : TsukimiBehaviour
{
void Start()
{
byte a = 200;
byte b = 200;
int sum = a + b;
Debug.Log(sum); // => 400
short s = 30000;
short t = 30000;
int total = s + t;
Debug.Log(total); // => 60000
}
}
using UnityEngine;
using Tsukimi;
public class NumericsIntegerDivision : TsukimiBehaviour
{
void Start()
{
int n = -7;
Debug.Log(n / 2); // => -3
Debug.Log(n % 2); // => -1
}
}

整数を 0 で割ると実行が止まりますが、小数では Infinity になります。

using UnityEngine;
using Tsukimi;
public class NumericsFloatDivideByZero : TsukimiBehaviour
{
void Start()
{
float one = 1f;
float zero = 0f;
Debug.Log(one / zero); // => Infinity
}
}

2 進の小数で表せない値があるので、10 進で書いたとおりの値にはなりません。C# と同じ結果になります。

using UnityEngine;
using Tsukimi;
public class NumericsDoublePrecision : TsukimiBehaviour
{
void Start()
{
double sum = 0.1 + 0.2;
Debug.Log(sum); // => 0.30000000000000004
}
}