This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/_archive/rhai_engine/rhaibook/language/numbers.md
2025-04-04 08:28:07 +02:00

5.5 KiB
Raw Blame History

Numbers

{{#include ../links.md}}

Integers


Integers can also be conveniently manipulated as [bit-fields].

Integer numbers follow C-style format with support for decimal, binary (0b), octal (0o) and hex (0x) notations.

The default system integer type (also aliased to INT) is i64. It can be turned into i32 via the [only_i32] feature.

Floating-Point Numbers


Both decimal and scientific notations can be used to represent floating-point numbers.

Floating-point numbers are also supported if not disabled with [no_float].

The default system floating-point type is f64 (also aliased to FLOAT). It can be turned into f32 via the [f32_float] feature.

Decimal Numbers

When rounding errors cannot be accepted, such as in financial calculations, the [decimal] feature turns on support for the [Decimal][rust_decimal] type, which is a fixed-precision floating-point number with no rounding errors.

Number Literals

_ separators can be added freely and are ignored within a number except at the very beginning or right after a decimal point (.).

Sample Format Value type [no_float] [no_float] + [decimal]
_123 improper separator
123_345, -42 decimal INT INT INT
0o07_76 octal INT INT INT
0xab_cd_ef hex INT INT INT
0b0101_1001 binary INT INT INT
123._456 improper separator
123_456.78_9 normal floating-point FLOAT syntax error [Decimal][rust_decimal]
-42. ending with decimal point FLOAT syntax error [Decimal][rust_decimal]
123_456_.789e-10 scientific notation FLOAT syntax error [Decimal][rust_decimal]
.456 missing leading 0
123.456e_10 improper separator
123.e-10 missing decimal 0

Warning No Implicit Type Conversions

Unlike most C-like languages, Rhai does not provide implicit type conversions between different numeric types.

For example, a u8 is never implicitly converted to i64 when used as a parameter in a function call or as a comparison operand. f32 is never implicitly converted to f64.

This is exactly the same as Rust where all numeric types are distinct. Rhai is written in Rust afterall.


Integer variables pushed inside a custom [`Scope`] must be the correct type.

It is extremely easy to mess up numeric types since the Rust default integer type is `i32` while for
Rhai it is `i64` (unless under [`only_i32`]).
use rhai::{Engine, Scope, INT};

let engine = Engine::new();

let mut scope = Scope::new();

scope.push("r", 42);            // 'r' is i32 (Rust default integer type)
scope.push("x", 42_u8);         // 'x' is u8
scope.push("y", 42_i64);        // 'y' is i64
scope.push("z", 42 as INT);     // 'z' is i64 (or i32 under 'only_i32')
scope.push("f", 42.0_f32);      // 'f' is f32

// Rhai integers are i64 (i32 under 'only_i32')
engine.eval::<String>("type_of(42)")? == "i64";

// false - i32 is never equal to i64
engine.eval_with_scope::<bool>(&mut scope, "r == 42")?;

// false - u8 is never equal to i64
engine.eval_with_scope::<bool>(&mut scope, "x == 42")?;

// true - i64 is equal to i64
engine.eval_with_scope::<bool>(&mut scope, "y == 42")?;

// true - INT is i64
engine.eval_with_scope::<bool>(&mut scope, "z == 42")?;

// false - f32 is never equal to f64
engine.eval_with_scope::<bool>(&mut scope, "f == 42.0")?;

Floating-Point vs. Decimal


When both [`no_float`] and [`decimal`] features are turned on, [`Decimal`][rust_decimal] _replaces_
the standard floating-point type.

Floating-point number literals in scripts parse to [`Decimal`][rust_decimal] values.

[Decimal][rust_decimal] (enabled via the [decimal] feature) represents a fixed-precision floating-point number which is popular with financial calculations and other usage scenarios where round-off errors are not acceptable.

[Decimal][rust_decimal] takes up more space (16 bytes) than a standard FLOAT (4-8 bytes) and is much slower in calculations due to the lack of CPU hardware support. Use it only when necessary.

For most situations, the standard floating-point number type FLOAT (f64 or f32 with [f32_float]) is enough and is faster than [Decimal][rust_decimal].

It is possible to use both FLOAT and [Decimal][rust_decimal] together with just the [decimal] feature use [parse_decimal] or [to_decimal] to create a [Decimal][rust_decimal] value.