Resources Numerical accuracy Calculation policy

CraftScript number type conversions

The script functions that convert values to single precision or to whole-number types.

How the precision is kept

The language keeps every number as a 64-bit value. single() rounds each value to the nearest 32-bit number with Math.fround and stores it back in a Float64Array, so later arithmetic is 64-bit on values that carry about 7 digits. The whole-number functions round but keep 64-bit storage and do not limit the range.

Open item. State in the help for single() that results carry about 7 digits, and make the whole-number functions round halves the same way round() does and limit values to each type's range.

Calculations under this policy

2 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.

cs-lib-core.js PartCraft 0.8.1 32-bit in part 2 calculations Reviewed

Tests tools/partcraft-test/test-craftscript-b.mjs

Conversion to single precision

32-bit in part

single(A): each value rounded to the nearest 32-bit floating-point number.

x ← fround(x)

This is what the function is for: the result is a 32-bit value stored in 64-bit form. Anything computed from it afterwards starts from about 7 significant digits.

  • cs-lib-core.js
  • line 222
  • PartCraft 0.8.1
def('single', (a) => { const t = T(a[0], 'single'); return out(t.shape, Float64Array.from(t.data, Math.fround)); }, 'single(A)');

Conversion to whole-number types

64-bit

int8, int16, int32, int64 and the unsigned forms: each value rounded to a whole number.

x ← round(x); NaN → 0

All eight names do the same thing: Math.round with no range limit and no sign check for the unsigned names. Halves round toward +∞. Values above 2⁵³ are already whole and pass through.

  • cs-lib-core.js
  • line 224
  • PartCraft 0.8.1
for (const name of ['int32', 'int64', 'int16', 'int8', 'uint8', 'uint16', 'uint32', 'uint64']) def(name, (a) => K.map(T(a[0], name), (x) => (x !== x ? 0 : Math.round(x))), `${name}(A)`);

In detail

Method
single: Math.fround per element. int8 … uint64: Math.round per element, NaN to 0.
Number types
Float64Array holding 32-bit-rounded or whole-number values.
Limits
The whole-number functions do not saturate or wrap: int8(1000) stays 1000. They use Math.round, which rounds halves toward +∞, so int32(−2.5) gives −2 while the language's round(−2.5) gives −3.

Approach: 32-bit step, flagged

One step stores or exchanges 32-bit values that reach a number a person reads. It is listed here with its open item, and the step is either moved to 64-bit or the app will warn where the number is read.

Every policy that takes this approach