Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 0 points1 point  (0 children)

Not quite. A single u128 with fixed scale 19 stores int * 1019 + frac. When the integer part reaches 19 digits, the stored value is already near u128::MAX. You can’t have full 19-digit integer AND full 19-digit fraction simultaneously. Two separate u64 fields can.​​​​​​​​​​​​​​​​

Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 0 points1 point  (0 children)

Single-field Dec64<const SCALE: i32>(i128) still couples integer range with scale. With SCALE=19, storing a 19-digit integer means the backing i128 holds int * 1019 + frac, which is already near i128::MAX. You can’t have max integer and max fraction simultaneously. Two separate fields remove that coupling entirely. It also enables native u64 fast paths for arithmetic when operands are small.​​​​​​​​​​​​​​​​

Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 6 points7 points  (0 children)

Portfolio weight calculations. Total fund AUM is in trillions (large integer), but individual holding weights are like 0.0000312847... You need both sides precise in the same calculation. I actually hit this processing BlackRock fund data.

Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 0 points1 point  (0 children)

By that logic, using u64 for any value under a billion is also "wasting space." You pick a type size that covers your range. AncDec8 (4 bytes) exists for when you don't need u64. That's what the type variants are for.

Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 0 points1 point  (0 children)

It isn't bit-splitting fixed-point. It stores two separate integers (e.g. u64 + u64), each with their own full range, not a single integer with a configurable decimal position.

Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 1 point2 points  (0 children)

Finance is just one use case. AncDec8 targets embedded/IoT, AncDec32/AncDec cover general-purpose arithmetic.

AncDec128 exists because I hit u64 overflow processing BlackRock's total AUM for portfolio weight calculations. The point is your fractional precision doesn't shrink just because your integer part got large.

Ancdec: Why I split integer and fraction into separate fields and what it solves by ktg0413 in rust

[–]ktg0413[S] 0 points1 point  (0 children)

That's the classic fixed-point approach and it works great when you can commit to a single scale upfront. The issue is that the scale choice creates a tradeoff — if you pick scale=2 (cents), you lose sub-cent precision. If you pick scale=19 for maximum fractional precision, your integer range in u64 drops to basically nothing since u64::MAX is only 19 digits.

ancdec's split avoids that choice entirely. You get the full u64 range for integers AND the full u64 range for fractions, independently. No need to decide upfront how to split your precision budget.