Types phase 2: economy/idle number correctness — decimal + bigint #52
Labels
No labels
area:ci
area:docs
area:input
area:net
area:rendering
area:repo
area:stdlib
area:tooling
area:types
cleanup
dx
priority:high
priority:low
priority:medium
proposal
status:in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: workshopsoft/ludic#52
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #1 (proposal), phase 2 of the phasing.
decimal — a 128-bit base-10 exact number (~28-29 significant digits), like C#
decimal, for tycoon/economy money: prices, balances and taxes that must add up exactly with no binary rounding on values like 0.10. Exact, so deterministic.bigint — an arbitrary-precision integer with no upper bound, like C#
BigInteger/ Gomath/big.Int, for idle counters, exact huge currencies, score hashing and deterministic RNG streams. Exact, so deterministic (slower).Both are the correct answer for money and exact large counts — prefer them over
fixedwhen the domain is currency, not physics. Neither introduces binary floating point.Phase 1 (IVec2 + Rect, alongside the pre-existing Vector and Color) shipped in the #1 thread.
Shipped —
BigInt+Decimal(bd6b12d)Types phase 2, the "money problem", is done. A self-contained bignum engine (
runtime/native/bignum.ludic, only compiler intrinsics) is spliced in on demand and exposed as two namespaces:BigInt.*— arbitrary-precision integer, sign-magnitude with base-1e9 limbs.from/parse,add/sub/mul/pow, integerdiv/mod,cmp/eq/is_zero,to_int,str. For idle/incremental counters and exact huge currencies that overflow a 32- or 64-bit int (e.g.BigInt.pow(BigInt.from(2), 100)=1267650600228229401496703205376).Decimal.*— exact base-10 fixed-point (aBigIntmantissa + a decimal scale).from/parse, exactadd/sub/mul,cmp/eq,scale/rescale(truncate toward zero),str. So the classic bug is gone:Decimal.add(Decimal.parse("0.10"), Decimal.parse("0.20"))is exactly"0.30", and1.5 == 1.50.Both are exact and therefore deterministic — no
f32/f64anywhere.Delivered following the Regex/Value precedent: the value type is the runtime struct (a
ptr), reached through the namespace and type inference, so no new type keyword was needed. Division that rounds (full bignum/bignum division andDecimal.div) is deliberately out of scope for this phase —BigInt.div/modby anintandDecimal.rescalecover the exact cases; a rounding-division API can follow if needed.Wired end to end: parser splice trigger (
g_uses_bignum),emit_calldispatch, reseeded C-free seed, a self-asserting example (examples/library/bignum.ludic, 16 assertions, in the regression suite), and per-symbol docs + section + inventory. All suites green:x test82/82,x selfhost-test30/30 (golden renders byte-identical, bootstrap fixpoint holds),x test-tools30/30,check-impl/check-vocabulary/check-docs.Closing phase 2. Phases 3-5 remain in #53 / #54 / #55.