Quantised Floats

Quantised floats are variable precision floats, encoded as bits. They are configured by the server and may change from demo to demo.

Initialisation

Parameters

When initialising a QF, there are four parameters specified by a serializer field.

Param NameTypeDescription
bit_countintThe number of bits a value will be encoded with
flagsint(8)Flags for configuring behaviour (see below)
low_valuefloat(32)(Optional) The smallest value encodable
high_valuefloat(32)(Optional) The largest value encodable

Flags

As seen above, the flag field allows different behaviour for a QF

Flag nameBitDescription
ROUND_DOWN0Read an extra bit, to quickly specify the lowest value
ROUND_UP1Read an extra bit, to quickly specify the highest value
ENCODE_ZERO2Read an extra bit, to quickly specify zero
ENCODE_INTS3Have no idea, there's maths involved and it looks scary

Setup

Setting up a QF is expensive and overcomplicated, much like my attempts at relationships.

Before getting into the weeds, there's two basic steps to perform:

  • When low or high values are not specified, they default to 0.0 and 1.0 respectively
  • When the bit_count is zero, or greater than or equal to 32, it's treated as a no-scale type.

Next, we recompute flags, removing invalid or unnecessary behaviour. Why are these flags present if the server disables them anyway? We'll never know. Thanks, Volvo.

  • if low_value is 0, and round down is set, then we unset encoding zero.
  • if high_value is 0, and round up is set, then we also unset encoding zero.
  • if low_value is 0, and encode zero is set, then we set round down, and unset encoding zero
  • if high_value is 0, and encode zero is set, then we set round up, and unset encoding zero
  • if low_value is greater than zero then we unset encoding zero
  • if high_value is less than zero then we unset encoding zero
  • if encode ints is set, then we unset every other flag
  • if round up and round_down are both set, then return an error.

Next, we want to calculate 3 values:

  • offset, the offset
  • dec_mul,
  • high_low_mul

The first step is to calculate the number of steps, essentially the size of the float. This should be equal to 1 << bit_count.

Next, do some rounding adjustment only if we round down, or round up:

  1. calculate the range of values.
  2. divide this range by the number of steps, this is offset
  3. offset the value by offset
    • if round down then subtract offset from high
    • if round up then add offset to low

Next, if encode_ints is true:

  1. calculate the range of values.
    • if this range is less, than one then set it to 1.0
  2. calculate the log2 and round up to the highest integer
  3. shift one by the rounded log, we'll call this target range,

Writers Note

This is incomplete!

The original end of this file read:

hahahha i give up why is this so fucked.