Negative base numbers: Difference between revisions
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: Add a few more tests) |
mNo edit summary |
||
Line 3: | Line 3: | ||
;Task: |
;Task: |
||
*Encode the decimal number 10 as negabinary |
*Encode the decimal number 10 as negabinary (expect 11110) |
||
*Encode the decimal number 146 as negaternary (expect 21102) |
*Encode the decimal number 146 as negaternary (expect 21102) |
||
*Encode the decimal number 15 as negadecimal (expect 195) |
*Encode the decimal number 15 as negadecimal (expect 195) |
Revision as of 02:10, 17 December 2016
Negative base numbers are an alternatively way to encode numbers without the need for a minus sign. Various negative bases may be used including negadecimal (base -10), negabinary (-2) and negaternary (-3).[1][2]
- Task
- Encode the decimal number 10 as negabinary (expect 11110)
- Encode the decimal number 146 as negaternary (expect 21102)
- Encode the decimal number 15 as negadecimal (expect 195)
- In each of the above cases, convert the encoded number back to decimal.
Perl 6
Perl 6 provides built-in methods / routines base and parse-base to convert to and from bases 2 through 36. We'll just shadow the core routines with versions that accept negative bases. We'll simplify things by only accepting integer values to convert.
<lang perl6>multi sub base (Int $value, Int $radix where -37 < * < -1) {
my @result = $value.polymod($radix xx *); for @result.kv -> $k, $v { if $v < 0 { @result[$k ] -= $radix; @result[$k + 1] += 1; } } @result.pop while @result.tail == 0; @result».=base($radix.abs); flip [~] @result;
}
multi sub parse-base (Str $str, Int $radix where -37 < * < -1) {
[+] $str.flip.comb.kv.map: { $^v.parse-base($radix.abs) * $radix ** $^k }
}
- TESTING
say ' 10.&base( -2) = ', 10.&base(-2); say ' 146.&base( -3) = ', 146.&base(-3); say ' 15.&base(-10) = ', 15.&base(-10); say ' 107.&base(-16) = ', 107.&base(-16); say ' 41371458.&base(-36) = ', 41371458.&base(-36);
say '"11110".&parse-base( -2) = ', "11110".&parse-base(-2); say '"21102".&parse-base( -3) = ', "21102".&parse-base(-3); say ' "195".&parse-base(-10) = ', "195".&parse-base(-10); say ' "1AB".&parse-base(-16) = ', "1AB".&parse-base(-16); say '"Perl6".&parse-base(-36) = ', "Perl6".&parse-base(-36);</lang>
- Output:
10.&base( -2) = 11110 146.&base( -3) = 21102 15.&base(-10) = 195 107.&base(-16) = 1AB 41371458.&base(-36) = PERL6 "11110".&parse-base( -2) = 10 "21102".&parse-base( -3) = 146 "195".&parse-base(-10) = 15 "1AB".&parse-base(-16) = 107 "Perl6".&parse-base(-36) = 41371458
Python
<lang python>#!/bin/python from __future__ import print_function
def EncodeNegBase(n, b): #Converts from decimal if n == 0: return "0" out = [] while n != 0: n, rem = divmod(n, b) if rem < 0: n += 1 rem -= b out.append(rem) return "".join(map(str, out[::-1]))
def DecodeNegBase(nstr, b): #Converts to decimal if nstr == "0": return 0
total = 0 for i, ch in enumerate(nstr[::-1]): total += int(ch) * b**i return total
if __name__=="__main__":
print ("Encode 10 as negabinary (expect 11110)") result = EncodeNegBase(10, -2) print (result) if DecodeNegBase(result, -2) == 10: print ("Converted back to decimal") else: print ("Error converting back to decimal")
print ("Encode 146 as negaternary (expect 21102)") result = EncodeNegBase(146, -3) print (result) if DecodeNegBase(result, -3) == 146: print ("Converted back to decimal") else: print ("Error converting back to decimal")
print ("Encode 15 as negadecimal (expect 195)") result = EncodeNegBase(15, -10) print (result) if DecodeNegBase(result, -10) == 15: print ("Converted back to decimal") else: print ("Error converting back to decimal")</lang>
- Output:
Encode 10 as negabinary (expect 11110) 11110 Converted back to decimal Encode 146 as negaternary (expect 21102) 21102 Converted back to decimal Encode 15 as negadecimal (expect 195) 195 Converted back to decimal
References
- ↑ Negabinary on Wolfram Mathworld
- ↑ Negative base on Wikipedia