OxCaml logo Jane Street logo

Small Numbers

The small numbers extension adds float32, int16, and int8 types to OxCaml. Currently, only float32 (single-precision IEEE float) is implemented.

Float32

When small numbers are enabled, the following float32 types are available:

float32
float32#
float32 array
float32# array

Literals use the s suffix:

1.0s  : float32
#1.0s : float32#

Pattern matching on float32s is not supported.

Operations

Operations on 32-bit floats are available via the Stdlib_stable.Float32 and Stdlib_stable.Float32_u libraries, which provide Base-like APIs.

Representation

The boxed float32 type is encoded as a custom block with similar semantics to int32. Similarly, float32 array is a typical OxCaml array containing boxed elements.

The float32# type is unboxed:

Like floats, compiler optimizations allow boxed float32s to remain unboxed while being manipulated within the scope of a function.

C ABI

Both boxed and unboxed float32s may be passed to C stubs. The OxCaml runtime provides helper functions for working with float32s.

external float32_stub : (float32[@unboxed]) -> (float32[@unboxed]) =
  "boxed_float32_stub" "unboxed_float32_stub"

external float32_hash_stub : float32# -> float32# =
  "boxed_float32_stub" "unboxed_float32_stub"

(* ... *)
#include <caml/float32.h>

float unboxed_float32_stub(float v) {
  return v;
}

value boxed_float32_stub(value v) {
  return caml_copy_float32(unboxed_float32_stub(Float32_val(v)));
}

Int8 / Int16

When small numbers are enabled, the following types are available:

int8
int8#
int16
int16#

Literals use s for int8 and S for int16:

42s  : int8
#42s : int8#
42S  : int16
#42S : int16#

Operations

Operations on small integers are available via the Stdlib_stable.Int8, Stdlib_stable.Int8_u, Stdlib_stable.Int16, and Stdlib_stable.Int16_u libraries.

Representation

Coming soon

Small int arrays

Coming soon

Untagged Char

When small numbers are enabled, the type char# is available.

Literals are prefixed with #:

#'a'     : char#
#'\123'  : char#
#'\o123' : char#
#'\xff'  : char#

Untagged char literals can be used in patterns, but not in ranges:

match x with
| #'a' -> f ()       (* allowed *)
| #'a'..#'z' -> g () (* not allowed *)

Operations

Operations on untagged chars are available via the Stdlib_stable.Char_u library.

Representation

Untagged chars have the same layout as int8#.