Skip to content

Numbers, casts & parsing

Numbers behave the way they do in normal C#. This page is the reference for the details that occasionally bite — the widths, the casts, unsigned wraparound, the constants, and parsing text into numbers.

The types

All the C# numeric types are here:

Type Range / meaning
byte / sbyte 8-bit unsigned (0–255) / signed (−128–127)
short / ushort 16-bit signed / unsigned
int / uint 32-bit signed / unsigned
long / ulong 64-bit signed / unsigned
float / double 32-bit / 64-bit floating point
char a 16-bit character code
bool true / false

decimal compiles and runs, but it's treated as a double under the hood — you don't get the extra base-10 precision real C# decimal gives, so don't use it for exact money math.

Literals

Write numbers the usual ways:

int a = 42;
uint b = 5u;              // u/U → uint
long c = 9_000_000_000L;  // l/L → long   (underscores are just spacers)
ulong d = 1ul;            // ul/UL → ulong
float e = 1.5f;           // f/F → float
double f = 2.0;           // no suffix on a decimal point → double
uint hex = 0xFFu;         // hex
int bits = 0b1010;        // binary
double sci = 1e6;         // scientific

A u-suffixed literal keeps its real unsigned value, so uint big = 3000000000u; holds 3000000000, not a wrapped negative.

Casts

Every numeric cast works and behaves like unchecked C# — narrowing truncates, it never errors:

byte x = (byte)300;      // 44   (wraps mod 256)
short s = (short)70000;  // 4464 (low 16 bits)
uint u = (uint)(-1);     // 4294967295
int i = (int)3.9f;       // 3    (truncates toward zero)
float g = (float)someLong;

Unsigned math (uint / ulong)

uint and ulong are fully unsigned — wraparound, unsigned comparison, unsigned division/modulo, bit operations and shifts all follow C# rules. That matters for hashing, bit-packing, and large IDs:

uint a = 1u, b = 2u;
uint c = a - b;          // 4294967295  (wraps at 2^32, not −1)

ulong big = 18446744073709551615u;
bool huge = big > 1;     // true  (compared as unsigned, not as −1)

Signed right-shift keeps the sign ((-8) >> 1 == -4); shifting a uint/ulong shifts in zeros, as it should.

Constants

The MaxValue / MinValue family and the floating-point specials all work:

int hi = int.MaxValue;          // 2147483647
long lo = long.MinValue;
byte bmax = byte.MaxValue;      // 255
float inf = float.PositiveInfinity;
float nan = float.NaN;          // and float.Epsilon, float.MaxValue, double.NaN, …

(Mathf.Infinity also works, but the type constants above read more clearly.)

Turning text into numbers

Parse works for every width, and the TryParse out form works too:

int n = int.Parse("42");
float f = float.Parse("3.14");

int result;
if (int.TryParse(userText, out result))   // safe: false instead of an error on bad input
    Debug.Log(result);

System.Convert is available as well — add using System; at the top of the file:

using System;

int a = Convert.ToInt32("42");
double d = Convert.ToDouble("3.14");
bool b = Convert.ToBoolean("true");
string s = Convert.ToString(123);

Convert.To* follows real C# rounding/parsing; on bad input it returns the type's default rather than throwing.

Operators & compound assignment

Arithmetic (+ - * / %), comparison, bitwise (& | ^ ~), and shifts (<< >>) all work. So does compound assignment — and not just on numbers, but on the Unity value types too:

int score = 0;  score += 10;         // numbers
byte b = 250;   b += 10;             // re-narrows like C#: b == 4

Color c = Color.white;  c *= 0.5f;   // dim a colour
Vector3 v = Vector3.one; v *= 2f;    // scale a vector
transform.position += velocity;      // move

A couple of edges

  • char prints as its number. In an interpolated string, $"{someChar}" shows the character code ("65"), not the letter. Use char values as numbers, or build the string a different way.
  • decimal is a double. It compiles, but there's no extra precision — see the type table above.

→ Related: Math & vectors, Collections.