Negative base

Uses your system voice; voice and rate in settings.

Snapshot

≈ 10 min read

Names in other languages

No names in other languages are held for this entry yet.

Article bodies are English and are not machine-translated. A name in another language is not a translation of the article.

A negative base (or negative radix) may be used to construct a non-standard positional numeral system. Like other place-value systems, each position holds multiples of the appropriate power of the system's base; but that base is negative—that is to say, the base is equal to for some natural number ( ). Negative-base systems can accommodate all the same numbers as standard place-value systems, but both positive and negative numbers are represented without the use of a minus sign (or, in computer representation, a sign bit); this advantage is countered by an increased complexity of arithmetic operations. The need to store the information normally contained by a negative sign often results in a negative-base number being one digit longer than its positive-base equivalent. The common names for negative-base positional numeral systems are formed by prefixing nega- to the name of the corresponding positive-base system; for example, negadecimal (base −10) corresponds to decimal (base 10), negabinary (base −2) to binary (base 2), negaternary (base −3) to ternary (base 3), and negaquaternary (base −4) to quaternary (base 4).

A negative base (or negative radix) may be used to construct a non-standard positional numeral system. Like other place-value systems, each position holds multiples of the appropriate power of the system's base; but that base is negative—that is to say, the base is equal to for some natural number ( ). Negative-base systems can accommodate all the same numbers as standard place-value systems, but both positive and negative numbers are represented without the use of a minus sign (or, in computer representation, a sign bit); this advantage is countered by an increased complexity of arithmetic operations. The need to store the information normally contained by a negative sign often results in a negative-base number being one digit longer than its positive-base equivalent. The common names for negative-base positional numeral systems are formed by prefixing nega- to the name of the corresponding positive-base system; for example, negadecimal (base −10) corresponds to decimal (base 10), negabinary (base −2) to binary (base 2), negaternary (base −3) to ternary (base 3), and negaquaternary (base −4) to quaternary (base 4). The representation (which is intended to be negadecimal notation) is equivalent to in decimal notation, because 10,000 + (−2,000) + 200 + (−40) + 3 = . Remark : On the other hand, in decimal would be written in negadecimal. a = \sum_{i=0}^{n}d_{i}(-r)^{i} where each digit is an integer from 0 to and the leading digit (unless ). The base expansion of is then given by the string . Negative-base systems may thus be compared to signed-digit representations, such as balanced ternary, where the radix is positive but the digits are taken from a partially negative range. (In the table below the digit of value −1 is written as the single character T.) Some numbers have the same representation in base as in base . For example, the numbers from 100 to 109 have the same representations in decimal and negadecimal. Similarly, 17=2^4+2^0=(-2)^4+(-2)^0 and is represented by 10001 in binary and 10001 in negabinary. Some numbers with their expansions in a number of positive and corresponding negative bases are: Note that, with the exception of nega balanced ternary, the base expansions of negative integers have an even number of digits, while the base expansions of the non-negative integers have an odd number of digits. -5 \div (-3) = 2 ~\mathrm{remainder}~ 1 has to be chosen — and not = 3 ~\mathrm{remainder}~ 4 nor = 1 ~\mathrm{remainder}~ -\!2. For example, to convert 146 in decimal to negaternary: \begin{array}{rr} 146 \div (-3) = & -48 ~\mathrm{remainder}~ 2 \\ -48 \div (-3) = & 16 ~\mathrm{remainder}~ 0 \\ 16 \div (-3) = & -5 ~\mathrm{remainder}~ 1 \\ -5 \div (-3) = & 2 ~\mathrm{remainder}~ 1 \\ 2 \div (-3) = & 0 ~\mathrm{remainder}~ 2 \end{array} Reading the remainders backward we obtain the negaternary representation of 146 10 : 21102 –3 . Proof: −3 · (−3 · (−3 · (−3 · ( 2 ) + 1 ) + 1 ) + 0 ) + 2 = (((2 · (−3) + 1) · (−3) + 1) · (−3) + 0) · (−3) + 2 = 146 10 . Reading the remainders forward we can obtain the negaternary least-significant-digit-first representation. Proof: 2 + ( 0 + ( 1 + ( 1 + ( 2 ) · −3 ) · −3) · −3 ) · −3 = 146 10 . Note that in most programming languages, the result (in integer arithmetic) of dividing a negative number by a negative number is rounded towards 0, usually leaving a negative remainder. In such a case we have . Because , is the positive remainder. Therefore, to get the correct result in such case, computer implementations of the above algorithm should add 1 and to the quotient and remainder respectively. static string ToNegabinary(int val) { string result = string.Empty; while (val != 0) { int remainder = val % -2; val = val / -2; if (remainder auto to_negabinary(int value) { std::bitset result; std::size_t bit_position = 0; while (value != 0) { const auto div_result = std::div(value, -2); if (div_result.rem static string Negaternary(int val) { string result = string.Empty; while (val != 0) { int remainder = val % -3; val = val / -3; if (remainder def negaternary(i: int) -> str: """Decimal to negaternary""" if i == 0: digits = ["0"] else: digits = [] while i != 0: i, remainder = divmod(i, -3) if remainder >>> negaternary(1000) '2212001' (defun negaternary (i) (if (zerop i) "0" (let ((digits "") (rem 0)) (loop while (not (zerop i)) do (progn (multiple-value-setq (i rem) (truncate i -3)) (when (minusp rem) (incf i) (incf rem 3)) (setf digits (concatenate 'string (write-to-string rem) digits)))) digits))) import java.util.ArrayList; import java.util.Collections; public ArrayList negativeBase(int input, int base) { ArrayList result_rev = new ArrayList<>(); int number = input; while (number != 0) { int i = number % base; number /= base; if (i The above gives the result in an ArrayList of integers, so that the code does not have to handle how to represent a base smaller than −10. To display the result as a string, one can decide on a mapping of base to characrters. For example: import java.util.stream.Collectors; final String alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_"; public String toBaseString(ArrayList lst) { // Would throw exception if base is beyond the 64 possible characters return lst.stream().map(n -> alphabet[n]).collect(Collectors.joining("")); } (defun negabase (num baz / dig rst) ;; NUM is any number. ;; BAZ is any number in the interval [-10, -2]. (This is forced by how we do string notation.) ;; ;; NUM and BAZ will be truncated to an integer if they're floats (e.g. 14.25 ;; will be truncated to 14, -123456789.87 to -123456789, etc.). (if (and (numberp num) (numberp baz) ( (fix baz) -11)) (progn (setq baz (float (fix baz)) num (float (fix num)) dig (if (= num 0) "0" "")) (while (/= num 0) (setq rst (- num (* baz (setq num (fix (/ num baz)))))) (if (minusp rst) (setq num (1+ num) rst (- rst baz))) (setq dig (strcat (itoa (fix rst)) dig))) dig) (progn (prompt (cond ((and (not (numberp num)) (not (numberp baz))) "\nWrong number and negabase.") ((not (numberp num)) "\nWrong number.") ((not (numberp baz)) "\nWrong negabase.") (t "\nNegabase must be inside [-10 -2] interval."))) (princ)))) the set D of output digits is standard, i.&nbsp;e. D = \{0, |b|-1\} with base b\in \{-2,-4\} , the output is coded in the same bitstring format, but the meaning of the places is another one. uint32_t toNegaBinary(uint32_t value) // input in standard binary { uint32_t Schroeppel2 = 0xAAAAAAAA; // = 2/3*((2*2)^16-1) = ...1010 return (value + Schroeppel2) ^ Schroeppel2; // eXclusive OR // resulting unsigned int to be interpreted as string of elements ε {0,1} (bits) } JavaScript port for the same shortcut calculation: function toNegaBinary(value) { const Schroeppel2 = 0xAAAAAAAA; // Convert as in C, then convert to a NegaBinary String return ( ( value + Schroeppel2 ) ^ Schroeppel2 ).toString(2); } The algorithm is first described by Schroeppel in the HAKMEM (1972) as item 128. The Wolfram MathWorld documents a version in the Wolfram Language by D. Librik (Szudzik). uint32_t toNegaQuaternary(uint32_t value) // input in standard binary { uint32_t Schroeppel4 = 0xCCCCCCCC; // = 4/5*((2*4)^8-1) = ...11001100 = ...3030 return (value + Schroeppel4) ^ Schroeppel4; // eXclusive OR // resulting unsigned int to be interpreted as string of elements ε {0,1,2,3} (pairs of bits) } JavaScript port for the same shortcut calculation: function toNegaQuaternary(value) { const Schroeppel4 = 0xCCCCCCCC; // Convert as in C, then convert to NegaQuaternary String return ( ( value + Schroeppel4 ) ^ Schroeppel4 ).toString(4); } The second row of this table, for instance, expresses the fact that −1 = 1 + 1 × −2; the fifth row says 2 = 0 + −1 × −2; etc. As an example, to add 1010101 (1 + 4 + 16 + 64 = 85) and 1110100 (4 + 16 − 32 + 64 = 52), Carry: 1 −1 0 −1 1 −1 0 0 0 First addend: 1 0 1 0 1 0 1 Second addend: 1 1 1 0 1 0 0 + -------------------------- Number: 1 −1 2 0 3 −1 2 0 1 Bit (result): 1 1 0 0 1 1 0 0 1 Carry: 0 1 −1 0 −1 1 −1 0 0 so the result is 110011001 (1 − 8 + 16 − 128 + 256 = 137). s_i = a_i \oplus b_i \oplus c_i^+ \oplus c_i^- c_{i+1}^+ = \overline{a_i}\overline{b_i}\overline{c_i^+}c_i^- c_{i+1}^- = a_i b_i \overline{c_i^-} + (a_i \oplus b_i)c_i^+ \overline{c_i^-} As an example, to compute 1101001 (1 − 8 − 32 + 64 = 25) minus 1110100 (4 + 16 − 32 + 64 = 52), Carry: 0 1 −1 1 0 0 0 First number: 1 1 0 1 0 0 1 Second number: −1 −1 −1 0 −1 0 0 + -------------------- Number: 0 1 −2 2 −1 0 1 Bit (result): 0 1 0 0 1 0 1 Carry: 0 0 1 −1 1 0 0 so the result is 100101 (1 + 4 −32 = −27). Unary negation, , can be computed as binary subtraction from zero, . Unlike positive-base systems, where integers and terminating fractions have non-unique representations (for example, in decimal 0.999... = 1) in negative-base systems the integers have only a single representation. However, there do exist rationals with non-unique representations. For the digits with \mathbf{t}:=r - 1 = -b - 1 the biggest digit and T:=0.\overline{01}_b = \sum_{i=1}^{\infty} b^{-2i} = \frac1{b^2-1} = \frac1{r^2-1} we have 0.\overline{0\mathbf{t}}_b=\mathbf{t}T=\frac{r\!-\!\!1}{r^2-1}=\frac1{r+1} &nbsp; &nbsp; as well as 1.\overline{\mathbf{t}0}_b = 1+\mathbf{t}bT = \frac{(r^2-1)+(r\!-\!\!1)b}{r^2-1}= \frac1{r+1}. So every number \frac1{r+1}+z with a terminating fraction z\in \Z r^{\Z} added has two distinct representations. For example, in negaternary, i.e. b=-3 and \mathbf{t}=2 , there is 1.\overline{02}_{(-3)} = \frac{5}{4} = 2.\overline{20}_{(-3)} . Such non-unique representations can be found by considering the largest and smallest possible representations with integer parts 0 and 1 respectively, and then noting that they are equal. (Indeed, this works with any integer-base system.) The rationals thus non-uniquely expressible are those of form \frac{z(r+1) + 1}{b^i(r + 1)} with z,i\in \Z.

Text derived from https://en.wikipedia.org/w/index.php?oldid=1368553303 under CC BY-SA 4.0; modifications have been made.