Skip to main content

One integer, one scale

An sfN value is a signed integer k, called the code, together with a fixed scale. Its value is
For sf16 the scale is 2^15 = 32768, so the code 16384 means 16384 / 32768 = 0.5, and the smallest step between two values (the LSB) is 1 / 32768. There is no exponent: the spacing between neighbouring values is the same everywhere, unlike floating point.

The range stops short of 1

Codes run from -M to +M with M = 2^(N-1) - 1. For sf16 that is -32767 to 32767, so the largest value is 32767 / 32768 = 0.999969482421875. 1.0 is not representable in any width, nor is -1.0, nor any other nonzero integer.
This matters in practice: x + 1, x / x and sf.ones(...) all hit this edge. The library tells you each time rather than quietly clipping.

The widths

Every width from 4 to 16 bits is available on the host. The device format is sf16; the narrower widths exist for experiments and for models that must fit in fewer bits. sf.info(dtype) returns these constants for any width:

Sign and magnitude on the wire

The chip stores a code as a sign bit plus a magnitude, not as two’s complement. x.bits gives that pattern; x.code gives the signed integer. They are the same for positive values and differ for negative ones.
Negative zero does not exist: sf.sf16(-0.0) is sf16(0.0).

What the format does not have

  • No NaN. A NaN input is an invalid event.
  • No infinity. An infinite input is an overflow event.
  • No subnormals and no exponent. The precision near 0 is the same as near 1.
The term Superfloat comes from the chip’s design; in fixed-point language sf16 is a Q1.15 number. Everything here follows from that one definition.

See also