# Numbers

## Integers

Tip: Bit-fields

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

Tip: Notations

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` 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 (`.`).

SampleFormatValue 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`
`-42.`ending with decimal point`FLOAT`syntax error`Decimal`
`123_456_.789e-10`scientific notation`FLOAT`syntax error`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.

Warning

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

Tip: `no_float` + `decimal`

When both `no_float` and `decimal` features are turned on, `Decimal` replaces the standard floating-point type.

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

`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` 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`.

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