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 Name | Type | Description |
|---|---|---|
bit_count | int | The number of bits a value will be encoded with |
flags | int(8) | Flags for configuring behaviour (see below) |
low_value | float(32) | (Optional) The smallest value encodable |
high_value | float(32) | (Optional) The largest value encodable |
Flags
As seen above, the flag field allows different behaviour for a QF
| Flag name | Bit | Description |
|---|---|---|
ROUND_DOWN | 0 | Read an extra bit, to quickly specify the lowest value |
ROUND_UP | 1 | Read an extra bit, to quickly specify the highest value |
ENCODE_ZERO | 2 | Read an extra bit, to quickly specify zero |
ENCODE_INTS | 3 | Have 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.0and1.0respectively - 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, andround downis set, then we unsetencoding zero. - if
high_value is 0, andround upis set, then we also unsetencoding zero. - if
low_value is 0, andencode zerois set, then we setround down, and unsetencoding zero - if
high_value is 0, andencode zerois set, then we setround up, and unsetencoding zero - if
low_value is greater than zerothen we unsetencoding zero - if
high_value is less than zerothen we unsetencoding zero - if
encode intsis set, then we unset every other flag - if
round upandround_downare both set, then return an error.
Next, we want to calculate 3 values:
offset, the offsetdec_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:
- calculate the range of values.
- divide this range by the number of steps, this is
offset - offset the value by offset
- if
round downthen subtract offset fromhigh - if
round upthen add offset tolow
- if
Next, if encode_ints is true:
- calculate the range of values.
- if this range is less, than one then set it to
1.0
- if this range is less, than one then set it to
- calculate the
log2and round up to the highest integer - 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.