Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Function

(int)x — casts

(int)<value> · (long)<value> · (decimal)<value> · (double)<value>

A C-style cast converts between the numeric types. It truncates toward zero, and it is checked — a value the target type cannot hold fails loudly rather than wrapping to a wrong number.

stable3 examples compiled by CIfunctionoperatortypesauthoring

Summary#

A cast converts a value from one numeric type to another: (int)x, (long)x, (decimal)x, (double)x. It truncates toward zero, exactly as C# does, and it is checked — a value the target type cannot hold fails with a message naming the value and the range, rather than silently wrapping.

Signature#

(int)<value>       // → int      32-bit; truncates toward zero
(long)<value>      // → long     64-bit; truncates toward zero
(decimal)<value>   // → decimal  exact base-10
(double)<value>    // → double   IEEE 754

Description#

When do I need a cast?#

Widening happens on its own: an int is usable where a double or a decimal is expected, because nothing is lost. Narrowing never happens on its own — dropping a fraction is a decision, so you write it down. A cast is how you write it.

The everyday case is a value that is fractional while it is being computed and whole once it is used: a grid cell from a position, a page number from a ratio, a pixel column from an angle.

int CellOf(double position, double cellSize) {
  return (int)(position / cellSize);      // the division is fractional; the cell index is not
}

It truncates toward ZERO#

(int)2.7 is 2 and (int)-2.7 is -2 — toward zero, not toward negative infinity. That matters for any value that can go negative (a camera coordinate, a delta, a temperature), where truncation and Math.Floor disagree:

value(int)vMath.Floor(v)
2.722
-2.7-2-3

If you want floor behaviour, say so — (int)Math.Floor(v) — and if you want a different rounding, choose it with Math.Abs, Math.Sign, Math.Min, Math.Max, Math.Clamp, Math.Truncate, Math.Pow, Math.Sqrt, Math.Sin, Math.Cos, Math.Tan before you narrow. A cast makes no rounding decision for you beyond dropping the fraction.

What happens when the value does not fit?#

C# is unchecked by default: (int)3000000000L is -1294967296 there, and (int)1e20 is formally undefined. Both are silent wrong answers, so Osy# does not reproduce them. A value outside the target's range fails:

cannot cast the value 3000000000 to 'int' — it is outside the range of 'int'
(-2147483648 … 2147483647). An Osy# cast is checked: it fails rather than wrapping to a wrong number.

The C# spelling that means the same thing is checked((int)x). NaN and ±Infinity have no integer or decimal value, so casting one of them to int, long or decimal fails too; both are ordinary values for (double).

The rule holds wherever the expression runs — in a function, in a UI action, in a frame body, and in a query pushed down to the database.

A cast does not parse, and it does not format#

A cast converts numbers. It does not parse, and it does not format:

you wrotewhat to write instead
(int)"42"Convert.ToInt(s) — a parse, which can fail; see Convert
(string)totaltotal.ToString()
(bool)countcount != 0

Each of those is a compile error naming the alternative. There is no cast to an entity, a class or an enum either — casting is the numeric conversion operator, nothing more.

Casting to decimal and double#

Both directions are legal and both are sometimes what you mean:

  • (decimal)aDouble takes C#'s conversion — 15 significant digits — so it is the deliberate move from fast to exact. Reach for it at the point money enters the calculation.
  • (double)aDecimal goes the other way, for geometry and physics, where agreeing with the browser's arithmetic matters more than base-10 exactness.
  • A cast to the type a value already has ((double)aDouble) is legal and does nothing.
decimal Price(double raw) { return (decimal)raw; }             // fast → exact
double Ratio(decimal part, decimal whole) {
  return (double)part / (double)whole;                          // exact → fast
}
long Micros(decimal amount) { return (long)(amount * 1000000m); }

Does (int)a * b cast a, or the product?#

A cast binds tighter than arithmetic, exactly as in C#: (int)a * b is ((int)a) * b. Parenthesise the expression when you mean to convert the whole thing — (int)(a * b).

(x) - y is still a subtraction. Only the four type keywords above introduce a cast, so a parenthesised name never becomes one by accident.

Examples#

int Truncated() { return (int)-2.7d; }                  // -2 — toward zero
int Floored() { return (int)Math.Floor(-2.7d); }        // -3 — the other rounding, said out loud
long Big(double v) { return (long)v; }
double AsDouble(int n) { return (double)n / 2d; }       // 2.5, not 2 — the cast makes it float division
int Column(double angle, double width) {
  return (int)(angle * width);                          // parenthesised: the product is narrowed
}

See also#

Related

Convert

Explicit conversion between types — number to text, text to number, a Guid to its text form. Osy# will not convert…

Math.Abs, Math.Sign, Math.Min, Math.Max, Math.Clamp, Math.Truncate, Math.Pow, Math.Sqrt, Math.Sin, Math.Cos, Math.Tan

The numeric helpers, each returning the type C# says it returns. Abs, Min, Max and Clamp answer in the WIDEST of their…

Numeric types & literal suffixes

The platform numeric types are int, long, decimal, and double. Literals follow C# exactly, suffixes (L, m, d) included:…

long

A 64-bit whole number, exact to its full range — ids, sequence numbers, row versions, byte offsets. It holds the same…