Solution (source code)

= Solution

The first proposed identity can fail even without numerical error because <binary fractions> have nonunique textual representations. Leading zeroes, optional points and trailing fractional zeroes are normalized differently by a fixed-width output convention. It also fails if the input has more significant bits than `Double` can preserve, more fractional places than the output buffer can hold, an <integer> part outside the assumed `Int` range, or a value that overflows or underflows during decoding. <Array> identity here must mean equal contents: a newly allocated <Scala> <array> is a different <software object>, so use `sameElements` rather than reference equality for a content test.

The second identity fails when the stored fractional precision truncates a nonzero bit; \b[with two fractional places, $0.125$ becomes zero]. It can also fail outside the finite nonnegative input and <integer>-conversion assumptions. Within those assumptions, enough fractional positions to encode the finite `Double` exactly can permit the round trip, but an arbitrary fixed small width does not guarantee it. Every finite `Double` has a finite <binary expansion>; saying that a decimal-looking `Double` necessarily has an infinite binary expansion would confuse the represented number with an exact decimal real.

The source's introductory example is internally inconsistent: the displayed digit <string> has value $22+1/4+1/32=22.28125$, whereas its shortened character <array> encodes $22+1/4+1/16=22.3125$. The conversion rules above follow the actual input digits. \b[<Round-trip testing> needs an independent value oracle as well as the two compositions], because two mutually consistent but incorrect routines can conceal each other's errors.