Casts round to nearest, ties to even
When a host number enters the format (constructing a value, quantizing an array, a literal in an expression), the exact value is multiplied by the scale and rounded to the nearest integer code. A tie goes to the even code.exact attribute shows the fraction you actually got, so you can see the rounding error:
Arithmetic truncates toward zero
Once values are in the format, the hardware computes on integers and drops any fractional part, always toward zero. There is no rounding step inside an operation.sf.
Division truncates too: sf.sf16(0.1) / sf.sf16(0.3) is sf16(0.333343505859375), code 10923, from 3277 × 32768 / 9830 = 10923.3.
Why the difference
Rounding on the way in gives the best possible representation of your data. Truncation inside the arithmetic is what the silicon does, because it is cheaper, and the library’s job is to match the silicon. If you compute something on the host in floats and compare withsf, expect the last code to differ in the direction of zero.
The operations, in one table
a * b + c and sf.fma(a, b, c) give the same bits: the product is truncated once in both. This is tested on every width.
Comparisons never round
<, == and friends compare the exact values. Comparing against a host number does not quantize it first: