Numbers - The `wasm-bindgen` Guide

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# Numbers: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `isize`, `usize`, `f32`, and `f64`

`T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation
--- | --- | --- | --- | --- | --- | ---
Yes | No | No | Yes | Yes | Yes | A JavaScript number or bigint value

JavaScript `Number`s are 64-bit floating point value under the hood and cannot accurately represent all of Rust's numeric types. `wasm-bindgen` will automatically use either `BigInt` or `Number` to accurately represent Rust's numeric types in JavaScript:

- `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, `usize`, `f32`, and `f64` will be represented as `Number` in JavaScript.
- `u64`, `i64`, `u128`, and `i128` will be represented as `BigInt` in JavaScript.

> Note: Wasm is currently a 32-bit architecture, so `isize` and `usize` are 32-bit integers and "fit" into a JavaScript `Number`.

> Note: `u128` and `i128` require `wasm-bindgen` version 0.2.96 or later.

## Converting from JavaScript to Rust

`wasm-bindgen` will automatically handle the conversion of JavaScript numbers to Rust numeric types. The conversion rules are as follows:

### `Number` to `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, and `usize`

If the JavaScript number is `Infinity`, `-Infinity`, or `NaN`, then the Rust value will be 0. Otherwise, the JavaScript number will rounded towards zero (see `Math.trunc` or `f64::trunc`). If the rounded number is too large or too small for the target integer type, it will wrap around.

For example, if the target type is `i8`, Rust will see the following values for the following inputs:

JS input number | Rust value (`i8`)
--- | ---
42 | 42
-42 | -42
1.999 | 1
-1.999 | -1
127 | 127
128 | -128
255 | -1
256 | 0
-0 | 0
`±Infinity` | 0
`NaN` | 0

This is the same behavior as assigning the JavaScript `Number` to a typed array of the appropriate integer type in JavaScript, i.e. `new Uint8Array([value])[0]`.

Except for the handling of `Infinity` and `-Infinity`, this is the same behavior as casting `f64` to the appropriate integer type in Rust, i.e. `value_f64 as u32`.

### `BigInt` to `u64`, `i64`, `u128`, and `i128`

If the JavaScript `BigInt` is too large or too small for the target integer type, it will wrap around.

This is the same behavior as assigning the JavaScript `BigInt` to a typed array for 64-bit integer types in JavaScript, i.e. `new Int64Array([value])[0]`.

### `Number` to `f32`

The JavaScript `Number` is converted to a Rust `f32` using the same rules as casting `f64` to `f32` in Rust, i.e. `value_f64 as f32`.

This is the same behavior as `Math.fround` or assigning the JavaScript `Number` to a `Float32Array` in JavaScript, i.e. `new Float32Array([value])[0]`.

### `Number` to `f64`

Since JavaScript numbers are 64-bit floating point values, converting a JavaScript `Number` to a Rust `f64` is a no-op.

## Example Rust Usage

    #![allow(unused)]
    fn main() {
    use wasm_bindgen::prelude::*;

    #[wasm_bindgen]
    pub fn take_number_by_value(x: u32) {}

    #[wasm_bindgen]
    pub fn return_number() -> f64 {
        42.0
    }

    #[wasm_bindgen]
    pub fn take_option_number(x: Option<u8>) {}

    #[wasm_bindgen]
    pub fn return_option_number() -> Option<i16> {
        Some(-300)
    }
    }

## Example JavaScript Usage

    import {
      take_number_by_value,
      return_number,
      take_option_number,
      return_option_number,
    } from './guide_supported_types_examples';

    take_number_by_value(42);

    let x = return_number();
    console.log(typeof x); // "number"

    take_option_number(null);
    take_option_number(undefined);
    take_option_number(13);

    let y = return_option_number();
    if (y == null) {
      // ...
    } else {
      console.log(typeof y); // "number"
    }