# Fixed-point as compression

### Any given fixed-point format can be considered a method of compressing another, higher resolution fixed-point format.

*This is part 4 of the onboarding floating point series. This series is intended to be used for onboarding of programmers new to the team to review a basic understanding of fixed-point and floating-point number formats, or for programmers who would like to remove some of the mystery from formats they may use everyday.*

We introduced **1:16:15 fixed-point **in fixed-point as fractions. Consider the following table of values. Assume they represent distances in meters, as in previous examples.

**Lossless compression**

Assuming these values are representative of some group (e.g. vertices of models, instance positions, etc), what can we see from the data?

There are a set of bits that are always zero. Values are within +/-32 meter range and 1/4096 meter resolution.

`-:00000000000-----:------------000`

Mark those bits with ‘x’ for “don’t care”

`-:xxxxxxxxxxx-----:------------xxx`

Mark bits that are used with letters for reference.

`S:xxxxxxxxxxxAAAAA:BBCCDDEEFFGGxxx`

Remove the bits we don’t care about.

`S:xxxxxxxxxxxxAAAA:BBCCDDEEFFGGxxx -> s:AAAA:BBCCDDEEFFGG`

```
uint32_t compress( uint32_t d )
{
return ((d&0x80000000)>>11)|((d&0xffff8)>>3);
}
```

Without losing any information, we can store these same values in 1:5:12 fixed-point format. However, that requires 18 bits of storage, so we might want to consider how we can reduce it to fit into 16 bits.

**Lossy compression**

1:5:12 fixed-point storage of distance has a resolution of 1/4096 meter, which is approximately 1/4 of a millimeter. In many common cases like game object model vertices or world positions, that resolution is imperceptible. We can often use 1/1024 meter resolution (or less!) without any difference perceivable by anyone other than the original artist. For any game that works with average human scale interactions, a millimeter is pretty small. Alternatively, if you’re making a game about brain surgery, nanometer resolution might be appropriate but anything more than a +/- 1 meter range is probably unnecessary.

If we don’t care about anything more than 1/1024 meter resolution, we can mark two additional bits ‘x’ as don’t care in the source 1:16:15 fixed-point data. By reasoning about what resolution we need, we can store the same values in a 1:5:10 format, which fits neatly into 16 bits.

`S:xxxxxxxxxxxAAAAA:BBCCDDEEFFxxxxx -> s:AAAAA:BBCCDDEEFF`

```
uint32_t compress( uint32_t d )
{
return ((d&0x80000000)>>16)|((d&0xfffd0)>>5);
}
```

Note that you can’t say whether or not compression is lossless or lossy without knowing concretely what data is being compressed.

**Take-away**

Consider fixed-point a form of compression. Select the appropriate size and format by considering the range and resolution necessary given the specific input data and how it’s used.

## Next: Part 5

Floating-point as compression - A floating-point format can be considered a (generally lossy) approach to compressing a high-resolution fixed-point format.