# Decimal Encoding

The Bullet exchange uses `rust_decimal::Decimal` (referred to as RustDecimal) for prices and sizes. This page explains
how to
encode a fixed-point integer (i64 value + u8 scale) into the 128-bit decimal layout used for borsh
serialization.

## Layout

A `RustDecimal` has four u32 fields:

| field   | bits                         | description                                    |
|---------|------------------------------|------------------------------------------------|
| `flags` | `[31]` sign, `[23:16]` scale | sign bit and decimal exponent                  |
| `hi`    | `[95:64]` of mantissa        | high 32 bits (zero when abs value fits in u64) |
| `lo`    | `[31:0]` of mantissa         | low 32 bits of the 96-bit mantissa             |
| `mid`   | `[63:32]` of mantissa        | middle 32 bits                                 | 

The mantissa is an unsigned 96-bit integer. The represented value is:

```text
(-1)^sign * mantissa / 10^scale
```

For borsh serialization the fields are ordered as: `flags, hi, lo, mid`.

## Converting from fixed-point to RustDecimal

If your system represents values as `i64` with a known scale (e.g. `N * 10^-scale`), the
conversion is straightforward — the absolute value of the i64 is the mantissa, and the scale
goes into the flags field.

### C++

<!-- @formatter:off -->
```cpp
{{#include decimal-example/decimal.cpp:rust_decimal}}
```
<!-- @formatter:on -->

### Python

<!-- @formatter:off -->
```python
{{#include decimal-example/decimal.py:rust_decimal}}
```
<!-- @formatter:on -->

### JavaScript

<!-- @formatter:off -->
```javascript
{{#include decimal-example/decimal.js:rust_decimal}}
```
<!-- @formatter:on -->

### Rust

The `rust_decimal` crate handles this natively — parse from string or construct via
`Decimal::from_parts(lo, mid, hi, negative, scale)`.

## Examples

| input | scale | decimal value | flags | hi | lo | mid |
|-------|-------|---------------|-------|----|----|-----|
| `100000000` | `8` | `1.00000000` | `0x00080000` | `0x00000000` | `0x05F5E100` | `0x00000000` |
| `-50000000` | `8` | `-0.50000000` | `0x80080000` | `0x00000000` | `0x02FAF080` | `0x00000000` |
| `123456789012` | `8` | `1234.56789012` | `0x00080000` | `0x00000000` | `0xBE991A14` | `0x0000001C` |
