build-a-bignum-library / lesson-07.md
Lesson 07 · Limbs, sign, and decimal I/O

String and the round-trip

The first chapter closes by joining sign and magnitude into the public String, then proving parse and render are exact inverses on genuinely large numbers - the first thing this library can really do.

The goal

Render a BigInt with its sign and confirm Parse and String round-trip exactly.

Start here - the target
TO DO
Scenario: Parse and String are exact inverses, sign included
Giventhe decimal string "18446744073709551616" (two to the sixty-fourth)
Whenit is parsed and rendered back with String()
Thenthe result is exactly "18446744073709551616"
AndParse("-18446744073709551616").String() is "-18446744073709551616", NewFromInt64(0).String() and Parse("-0").String() are both "0", and Parse("007").String() is "7"
Background

String is the small cap on the chapter: for zero return "0", otherwise render the magnitude and prepend a - when the sign is negative. Because zero is canonical, there is no negative-zero branch to worry about - Parse("-0") already carries sign 0, so it prints "0".

The real point of today is the round-trip. Parse and String should be exact inverses on the canonical form: parse a string, render it, and get back the same digits (minus any leading zeros or a spurious minus). Two to the sixty-fourth, 18446744073709551616, is far past what a 64-bit integer can hold, yet it survives the loop limb for limb. That closed loop - exact in, exact out, at arbitrary size - is the foundation every arithmetic operation from here will be checked against.

Make it work
func (x BigInt) String() string {
if x.sign == 0 { return "0" }
s := x.mag.String()
if x.sign < 0 { return "-" + s }
return s
}
CheckpointDONE
The library reads and writes signed big decimals exactly. Commit and stop here.