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

Reference / Function

Numeric types & literal suffixes

5 (int) · 5000000000L (long) · 2.5 (double) · 2.5m (decimal)

The platform numeric types are int, long, decimal, and double. Literals follow C# exactly, suffixes (L, m, d) included: a bare decimal-point literal is a DOUBLE, and money is written 19.99m. There is no float: 2.5f is a pointed compile error.

stable1 example compiled by CIfunctiontypesauthoring

Summary#

The platform numeric types are int (Int32), long (Int64), decimal, and double. Numeric literals follow C#, with no divergence at all: a bare integer is int, a bare decimal-point literal (2.5) is a double, L makes a long, m a decimal, d a double. There is no float type; 2.5f is a pointed compile error.

This page said the opposite until 2026-08-31, describing a bare 2.5 as a decimal "money-safe default". That divergence was real and was removed on 2026-08-12; the page was not updated with it, so it taught a spelling the compiler rejects — decimal Price() { return 19.99; } does not compile.

Signature#

5              // int
5000000000L    // long  (values past int.MaxValue need the suffix)
2.5            // double — same as C#, and same as every other unsuffixed fractional literal
2.5m           // decimal — what money is written as
2.5d           // double

Description#

  • No float. The platform numeric model has no float type; 2.5f refuses with float literals … are not supported — the platform numeric types are int/long/decimal/double.
  • Bare 2.5 is a double, exactly as in C#. It was a decimal until 2026-08-12, and that was the one place Osy#'s literals disagreed with the language they mirror — a disagreement invisible until arithmetic overflows. A canvas whose fields were all double ran entirely in decimal because every literal initialising them was one, and threw "value was either too large or too small for a Decimal" naming a type the source never wrote.
  • Money is safe BECAUSE of this, not despite it. C#'s rule is a PAIR: 1.0 is a double AND there is no implicit doubledecimal. Osy# keeps both halves, so decimal price = 19.99; is a compile error and the author writes 19.99m — strictly safer than a default that made every literal a decimal whether the surrounding expression wanted one or not.
  • Arithmetic runs in the decimal lattice (matching Postgres): a double operand behaves like any non-integral number — 5d / 2 == 2.5 (a double defeats integer truncation, as in C#), while int÷int truncates (5 / 2 == 2, SQL parity).
  • Round-trip: suffixed literals persist as typed literal nodes and decompile ALWAYS suffixed (5000000000L, 5d), so the canonical form re-lexes identically.
  • Durable: across a suspend/resume, a double local resumes as decimal (the codec's numeric normalization — the same value under the decimal arithmetic lattice).
  • const composes: const double factor = 1.5d; folds and inlines like every const.

Examples#

long Big() { return 5000000000L; }      // past int.MaxValue — needs the L
double Half() { return 5d / 2; }        // == 2.5 — the double defeats integer truncation
decimal Price() { return 19.99m; }      // money takes the m — a bare 19.99 is a double and will not convert
double Rate() { const double f = 1.5d; return f; }

See also#

  • Typed locals — declared types + the constant conversion (double h = 2.5; works)
  • const — const folding and inlining

Related

Typed locals

Locals can declare an explicit type instead of var; the declared type pins the binding. Literal initializers apply the…

const

A value fixed at compile time and folded into the places it is used. Declare one at the TOP LEVEL to share it across…