Binary codes of numbers in polynomial time #
Converting between a number written in unary, which is how
Complexitylib.Classes.P.Unary writes a polynomial-time number, and the same
number written in binary, least significant bit first, as Nat.toBitsLE,
Nat.fromBitsLE and Nat.bits do.
Writing binary is polynomial-time without any side condition. The width-w
expansion of n (toBitsLE_mem_FP) lists bit i of n at position i
(toBitsLE_eq_map_range), and each bit is a polynomial-time test on i. The
minimal expansion Nat.bits n (bits_mem_FP) is the expansion at width
Nat.size n.
Reading binary can only be polynomial-time up to a cap, because a numeral of
k bits can denote a number near 2 ^ k, far too large to write in unary. The
value capped at a polynomial-time number is polynomial-time
(UnaryFn.fromBitsLE_min), and so is the value itself when the cap is known not
to bind (UnaryFn.fromBitsLE_of_le).
Main results #
toBitsLE_eq_map_range— the fixed-width expansion, bit by bittoBitsLE_mem_FP— writing a fixed-width expansion is polynomial-timebits_mem_FP,bits_length_mem_FP— writing the minimal expansion is polynomial-timeUnaryFn.fromBitsLE_min,UnaryFn.fromBitsLE_of_le— reading a numeral back, below a cap, is polynomial-time
Writing binary #
Reading binary #
Reading a numeral below a cap is polynomial-time. If s ∈ FP and c is
a polynomial-time number, then so is the value of s z, read least significant
bit first, capped at c z. (Inside the UnaryFn namespace a bare min means
UnaryFn.min, hence Min.min.)
Reading a numeral is polynomial-time when its value is at most a polynomial-time number.