1
0
Fork 0
forked from fun/fun
fun/web/documentation/numbers/numbers.md

4.7 KiB
Raw Blame History

layout published noToc noComments noDate title subtitle description permalink lang tags
page true false false false Fun - Working with numbers and floats in Fun Working with integers and floats, arithmetic, conversions, clamping, bitwise ops, and patterns. Working with integers and floats, arithmetic, conversions, clamping, bitwise ops, and patterns. /documentation/numbers/ en
arithmetic
bitwise
clamping
conversions
floats
integers
numbers
ops
patterns

This guide covers the numeric types in Fun, with a focus on the integer "number" type and the 64bit floating point "float" type. Youll find creation, arithmetic, conversion, clamping, bitwise operations, and common patterns.

TL;DR

  • number = signed integer; float = 64bit floating point.
  • Use +, -, *, / for arithmetic. If you need fractional results, make at least one operand a float.
  • Modulo: a % b. Integer division with / may discard the fractional part; cast to float to preserve it.
  • Convert/parse: to_number("123"), to_string(x), cast(x, "float"), cast(x, "number").
  • Clamp to widths when interfacing with external code: uclamp(n, bits), sclamp(n, bits).
  • Bitwise (numbers only): &, |, ^, ~, <<, >>.

Numeric types at a glance

  • number: signed integer (implementationdefined width; use uclamp/sclamp for fixedwidth interop)
  • float: IEEE754 double precision (64bit)
an = 42            // number
af = 3.14159       // float
print(typeof(an))  // "number"
print(typeof(af))  // "float"

Literals

  • Integer (number): 0, 1, -7, 120
  • Floating point (float): 0.0, 1.5, -2.75, 1e3, -4.2e-1
x = 10
y = 2.5
z = -3

Arithmetic

Basic arithmetic works as youd expect:

a = 7
b = 2
print(a + b)   // 9
print(a - b)   // 5
print(a * b)   // 14
print(a % b)   // 1 (modulo)

Division and result type:

// If you need a fractional result, ensure a float is involved
print(7 / 2)                    // implementation may yield 3 or 3.5 depending on numeric rules
print(cast(7, "float") / 2)    // 3.5 (recommended when you need fractions)
print(7 / 2.0)                  // 3.5

Mixing numbers and floats promotes the operation to float semantics:

print(2 + 0.5)   // 2.5

Comparisons

print(3 < 5)     // 1 (true)
print(3 == 3)    // 1
print(3 != 4)    // 1

// Be explicit when comparing ints vs floats if types matter
print(1 == 1.0)              // may be true, but types differ
print(cast(1.0, "number") == 1) // 1 (true) with explicit cast

Conversions and parsing

n = to_number("123")        // 123 (number)
f = cast(n, "float")        // 123.0 (float)
n2 = cast(3.9, "number")    // 3 (truncation semantics)
print(to_string(f))          // "123"

If parsing fails (e.g., to_number("abc")), expect a runtime error; guard accordingly.

Clamping to fixed widths

When interoperating with bytecode, C APIs, or binary formats, clamp integers to a specific bit width.

// Unsigned clamp to N bits
u8  = uclamp(300, 8)   // 44
u16 = uclamp(70000, 16)

// Signed clamp to N bits
s8  = sclamp(-130, 8)  // wraps into signed 8bit range

Choose the bits according to the target field (8, 16, 32, 64). See your interop API docs for exact ranges.

Bitwise operations (numbers)

Bitwise operators apply to the integer number type.

a = 0b0110  // if binary literals arent supported in your setup, use decimals: a = 6
b = 0b0011  // or b = 3

print(a & b)  // 0b0010 -> 2
print(a | b)  // 0b0111 -> 7
print(a ^ b)  // 0b0101 -> 5
print(~a)     // bitwise NOT (twos complement rules)
print(a << 1) // 12
print(a >> 1) // 3

Note: Bitwise ops are defined for numbers, not floats. Cast floats to numbers first when needed.

Common patterns

Ensuring float math to avoid unintended truncation:

avg = cast(sum, "float") / cast(count, "float")

Safe division with guard against zero:

num = 10
den = 0
if den == 0 {
  print("division by zero")
} else {
  print(num / den)
}

Parsing user input with fallback:

raw = "not-a-number"
val = 0
// simplistic guard pattern; adapt to your error handling style
if find(raw, "0") >= 0 || find(raw, "1") >= 0 {  // crude pre-check
  val = to_number(raw)
}

Gotchas

  • Integer division vs float division: promote to float when you need fractional results.
  • Overflow/underflow: clamp explicitly when targeting fixedwidth fields; otherwise values follow the VMs integer semantics.
  • Bitwise with negatives uses twos complement; ~x equals -(x+1).

See also