Negative base numbers: Difference between revisions

added RPL
(Added Scala)
(added RPL)
(47 intermediate revisions by 22 users not shown)
Line 15:
* supply an integer, that when encoded to base &nbsp; -62 &nbsp; (or something "higher"), &nbsp; expresses the <br>name of the language being used &nbsp; (with correct capitalization). &nbsp; If the computer language has <br>non-alphanumeric characters, &nbsp; try to encode them into the negatory numerals, &nbsp; or use other <br>characters instead.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F encode_neg_base(=n, b)
I n == 0
R ‘0’
[Int] out
L n != 0
(n, V rem) = divmod(n, b)
I rem < 0
n++
rem -= b
out.append(rem)
R reversed(out).map(String).join(‘’)
 
F decode_neg_base(nstr, b)
I nstr == ‘0’
R 0
V total = 0
L(ch) reversed(nstr)
V i = L.index
total += Int(ch) * b ^ i
R total
 
print(‘Encode 10 as negabinary (expect 11110)’)
V result = encode_neg_base(10, -2)
print(result)
I decode_neg_base(result, -2) == 10
print(‘Converted back to decimal’)
E
print(‘Error converting back to decimal’)
print(‘Encode 146 as negaternary (expect 21102)’)
result = encode_neg_base(146, -3)
print(result)
I decode_neg_base(result, -3) == 146
print(‘Converted back to decimal’)
E
print(‘Error converting back to decimal’)
print(‘Encode 15 as negadecimal (expect 195)’)
result = encode_neg_base(15, -10)
print(result)
I decode_neg_base(result, -10) == 15
print(‘Converted back to decimal’)
E
print(‘Error converting back to decimal’)</syntaxhighlight>
 
{{out}}
<pre>
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
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">CHAR ARRAY digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"
 
INT FUNC MyMod(INT a,b)
IF b>=0 THEN
RETURN (a MOD b)
FI
RETURN (a-(b*(a/b)))
 
PROC Encode(INT n,base CHAR ARRAY res)
INT i,d,len
CHAR tmp
 
IF base<-63 OR base>-1 THEN Break() FI
IF n=0 THEN SAssign(res,"0") FI
 
len=0
WHILE n#0
DO
d=MyMod(n,base)
n==/base
IF d<0 THEN
n==+1
d==-base
FI
len==+1
res(len)=digits(d+1)
OD
res(0)=len
 
FOR i=1 to len/2
DO
tmp=res(i)
res(i)=res(len-i+1)
res(len-i+1)=tmp
OD
RETURN
 
BYTE FUNC Index(CHAR ARRAY s CHAR c)
BYTE i
 
FOR i=1 TO s(0)
DO
IF s(i)=c THEN RETURN (i) FI
OD
RETURN (0)
 
INT FUNC Decode(CHAR ARRAY s INT base)
INT res,b,i,pos
 
IF base<-63 OR base>-1 THEN Break() FI
IF s(0)=1 AND s(1)='0 THEN RETURN (0) FI
 
res=0
b=1
pos=s(0)
WHILE pos>=1
DO
i=Index(digits,s(pos))-1
res==+i*b
b==*base
pos==-1
OD
RETURN (res)
 
PROC Test(INT n,base)
CHAR ARRAY s(20)
INT v
 
Encode(n,base,s)
PrintF("%I encoded in base %I is %S%E",n,base,s)
v=Decode(s,base)
PrintF("%S decoded in base %I is %I%E%E",s,base,v)
RETURN
 
PROC Main()
INT v
Test(10,-2)
Test(146,-3)
Test(15,-10)
Test(-568,-63)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Negative_base_numbers.png Screenshot from Atari 8-bit computer]
<pre>
10 encoded in base -2 is 11110
11110 decoded in base -2 is 10
 
146 encoded in base -3 is 21102
21102 decoded in base -3 is 146
 
15 encoded in base -10 is 195
195 decoded in base -10 is 15
 
-568 encoded in base -63 is A!
A! decoded in base -63 is -568
</pre>
 
=={{header|Ada}}==
{{trans|Modula}}
 
<syntaxhighlight lang="ada">with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
 
package Negative_Base_Numbers is
 
subtype base_t is Long_Long_Integer range -62 .. -1;
 
function Encode_Negative_Base
(N : in Long_Long_Integer; Base : in base_t) return Unbounded_String;
function Decode_Negative_Base
(N : in Unbounded_String; Base : in base_t) return Long_Long_Integer;
 
end Negative_Base_Numbers;
 
with Ada.Text_IO;
package body Negative_Base_Numbers is
 
Digit_Chars : constant String :=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
--------------------------
-- Encode_Negative_Base --
--------------------------
 
function Encode_Negative_Base
(N : in Long_Long_Integer; Base : in base_t) return Unbounded_String
is
procedure swap (a, b : in out Character) is
temp : Character := a;
begin
a := b;
b := temp;
end swap;
 
Result : Unbounded_String := Null_Unbounded_String;
Local_N : Long_Long_Integer := N;
Remainder : Long_Long_Integer;
 
begin
if Local_N = 0 then
Result := To_Unbounded_String ("0");
else
while Local_N /= 0 loop
Remainder := Local_N rem Base;
Local_N := Local_N / Base;
if Remainder < 0 then
Local_N := Local_N + 1;
Remainder := Remainder - Base;
end if;
Append (Result, Digit_Chars (Integer (Remainder + 1)));
end loop;
end if;
 
declare
Temp_Result : String := To_String (Result);
Low : Positive := Temp_Result'First;
High : Positive := Temp_Result'Last;
begin
while Low < High loop
swap (Temp_Result (Low), Temp_Result (High));
Low := Low + 1;
High := High - 1;
end loop;
Result := To_Unbounded_String (Temp_Result);
end;
 
return Result;
end Encode_Negative_Base;
 
--------------------------
-- Decode_Negative_Base --
--------------------------
 
function Decode_Negative_Base
(N : in Unbounded_String; Base : in base_t) return Long_Long_Integer
is
Total : Long_Long_Integer := 0;
bb : Long_Long_Integer := 1;
Temp : String := To_String (N);
begin
if Length (N) = 0 or else (Length (N) = 1 and Element (N, 1) = '0') then
return 0;
end if;
 
for char of reverse Temp loop
for J in Digit_Chars'Range loop
if char = Digit_Chars (J) then
Total := Total + Long_Long_Integer (J - 1) * bb;
bb := bb * Base;
end if;
end loop;
end loop;
 
return Total;
end Decode_Negative_Base;
 
end Negative_Base_Numbers;
 
with Ada.Text_IO; use Ada.Text_IO;
with Negative_Base_Numbers; use Negative_Base_Numbers;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
 
procedure Main is
 
procedure driver (N : in Long_Long_Integer; B : in base_t) is
package long_IO is new Integer_IO (Long_Long_Integer);
use long_IO;
 
ns : Unbounded_String := Encode_Negative_Base (N, B);
P : Long_Long_Integer;
Output : String (1 .. 12);
 
begin
Put (Item => N, Width => 12);
Put (" encoded in base ");
Put (Item => B, Width => 3);
Put_Line (" = " & To_String (ns));
 
Move
(Source => To_String (ns), Target => Output,
Justify => Ada.Strings.Right);
P := Decode_Negative_Base (ns, B);
Put (Output & " decoded in base ");
Put (Item => B, Width => 3);
Put (" = ");
Put (Item => P, Width => 1);
New_Line (2);
end driver;
 
begin
driver (10, -2);
driver (146, -3);
driver (15, -10);
driver (36_058, -62);
end Main;</syntaxhighlight>
{{out}}
<pre>
10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
36058 encoded in base -62 = Ada
Ada decoded in base -62 = 36058</pre>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
<langsyntaxhighlight lang="algol68"># Conversion to/from negative base numbers #
# Note - no checks for valid bases or digits bases -2 .. -63 are handled #
# A-Z represent the digits 11 .. 35, a-z represent the digits 36 .. 61 #
Line 86 ⟶ 395:
# The defining document for ALGOL 68 spells the name "Algol 68" on the cover, though inside it is "ALGOL 68" #
# at the risk of "judging a language by it's cover", we use "Algol 68" as the name here... #
test n base( - LONG 36492107981104, -63, "Algol 68" )</langsyntaxhighlight>
{{out}}
<pre>
Line 98 ⟶ 407:
Algol 68 decodes to: -36492107981104 base -63
</pre>
 
=={{header|C}}==
{{trans|modula-2}}
<syntaxhighlight lang="c">#include <stdio.h>
 
const char DIGITS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const int DIGITS_LEN = 64;
 
void encodeNegativeBase(long n, long base, char *out) {
char *ptr = out;
 
if (base > -1 || base < -62) {
/* Bounds check*/
out = "";
return;
}
if (n == 0) {
/* Trivial case */
out = "0";
return;
}
 
/* Convert the number into a string (in reverse) */
while (n != 0) {
long rem = n % base;
n = n / base;
if (rem < 0) {
n++;
rem = rem - base;
}
*ptr = DIGITS[rem];
ptr++;
}
*ptr = 0;
 
/* Reverse the current string to get the final result */
ptr--;
while (out < ptr) {
char t = *out;
*out = *ptr;
*ptr = t;
out++;
ptr--;
}
return;
}
 
long decodeNegativeBase(const char* ns, long base) {
long value, bb;
int i;
const char *ptr;
 
if (base < -62 || base > -1) {
/* Bounds check */
return 0;
}
if (ns[0] == 0 || (ns[0] == '0' && ns[1] == 0)) {
/* Trivial case */
return 0;
}
 
/* Find the end of the string */
ptr = ns;
while (*ptr != 0) {
ptr++;
}
 
/* Convert */
value = 0;
bb = 1;
ptr--;
while (ptr >= ns) {
for (i = 0; i < DIGITS_LEN; i++) {
if (*ptr == DIGITS[i]) {
value = value + i * bb;
bb = bb * base;
break;
}
}
ptr--;
}
 
return value;
}
 
void driver(long n, long b) {
char buf[64];
long value;
 
encodeNegativeBase(n, b, buf);
printf("%12d encoded in base %3d = %12s\n", n, b, buf);
 
value = decodeNegativeBase(buf, b);
printf("%12s decoded in base %3d = %12d\n", buf, b, value);
 
printf("\n");
}
 
int main() {
driver(10, -2);
driver(146, -3);
driver(15, -10);
driver(12, -62);
 
return 0;
}</syntaxhighlight>
{{out}}
<pre> 10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
12 encoded in base -62 = C
C decoded in base -62 = 12</pre>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace NegativeBaseNumbers {
class Program {
const string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
static string EncodeNegativeBase(long n, int b) {
if (b < -62 || b > -1) {
throw new ArgumentOutOfRangeException("b");
}
if (n == 0) {
return "0";
}
StringBuilder output = new StringBuilder();
long nn = n;
while (nn != 0) {
int rem = (int)(nn % b);
nn /= b;
if (rem < 0) {
nn++;
rem -= b;
}
output.Append(DIGITS[rem]);
}
return new string(output.ToString().Reverse().ToArray());
}
 
static long DecodeNegativeBase(string ns, int b) {
if (b < -62 || b > -1) {
throw new ArgumentOutOfRangeException("b");
}
if (ns == "0") {
return 0;
}
long total = 0;
long bb = 1;
for (int i = ns.Length - 1; i >= 0; i--) {
char c = ns[i];
total += DIGITS.IndexOf(c) * bb;
bb *= b;
}
return total;
}
 
static void Main(string[] args) {
List<Tuple<long, int>> nbl = new List<Tuple<long, int>>() {
new Tuple<long, int>(10,-2),
new Tuple<long, int>(146,-3),
new Tuple<long, int>(15,-10),
new Tuple<long, int>(-34025238427,-62),
};
foreach (var p in nbl) {
string ns = EncodeNegativeBase(p.Item1, p.Item2);
Console.WriteLine("{0,12} encoded in base {1,-3} = {2}", p.Item1, p.Item2, ns);
long n = DecodeNegativeBase(ns, p.Item2);
Console.WriteLine("{0,12} decoded in base {1,-3} = {2}", ns, p.Item2, n);
Console.WriteLine();
}
}
}
}</syntaxhighlight>
{{out}}
<pre> 10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
-34025238427 encoded in base -62 = csharp
csharp decoded in base -62 = -34025238427</pre>
 
=={{header|C++}}==
{{trans|C#}}
<syntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
#include <tuple>
#include <vector>
 
const std::string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
std::string encodeNegativeBase(int64_t n, int b) {
if (b < -62 || b > -1) {
throw std::runtime_error("Argument out of range: b");
}
if (n == 0) {
return "0";
}
 
std::string output;
int64_t nn = n;
while (nn != 0) {
int rem = nn % b;
nn /= b;
if (rem < 0) {
nn++;
rem -= b;
}
output += DIGITS[rem];
}
 
std::reverse(output.begin(), output.end());
return output;
}
 
int64_t decodeNegativeBase(const std::string& ns, int b) {
if (b < -62 || b > -1) {
throw std::runtime_error("Argument out of range: b");
}
if (ns == "0") {
return 0;
}
 
int64_t total = 0;
int64_t bb = 1;
 
for (auto it = ns.crbegin(); it != ns.crend(); it = std::next(it)) {
auto ptr = std::find(DIGITS.cbegin(), DIGITS.cend(), *it);
if (ptr != DIGITS.cend()) {
auto idx = ptr - DIGITS.cbegin();
total += idx * bb;
}
bb *= b;
}
return total;
}
 
int main() {
using namespace std;
 
vector<pair<int64_t, int>> nbl({
make_pair(10, -2),
make_pair(146, -3),
make_pair(15, -10),
make_pair(142961, -62)
});
 
for (auto& p : nbl) {
string ns = encodeNegativeBase(p.first, p.second);
cout << setw(12) << p.first << " encoded in base " << setw(3) << p.second << " = " << ns.c_str() << endl;
 
int64_t n = decodeNegativeBase(ns, p.second);
cout << setw(12) << ns.c_str() << " decoded in base " << setw(3) << p.second << " = " << n << endl;
 
cout << endl;
}
 
return 0;
}</syntaxhighlight>
{{out}}
<pre> 10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
142961 encoded in base -62 = cpp
cpp decoded in base -62 = 142961</pre>
 
=={{header|D}}==
<langsyntaxhighlight Dlang="d">import std.stdio;
 
immutable DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Line 161 ⟶ 757:
}
return total;
}</langsyntaxhighlight>
 
{{out}}
Line 175 ⟶ 771:
13 encoded in base -62 = D
D decoded in base -62 = 13</pre>
 
=={{header|F_Sharp|F#}}==
===The Functions===
<syntaxhighlight lang="fsharp">
//I provide 2 fuctions D2N takes a radix and an integer returning a sequence of integers
// N2D takse a radix and a sequence of integers returning an integer
//Note that the radix may be either positive or negative. Nigel Galloway, May 10th., 2019
let D2N n g=if g=0 then seq[0] else Seq.unfold(fun g->let α,β=g/n,g%n in match (compare g 0,β) with
(0,_)->None
|(1,_) |(_,0)->Some(β,α)
|_->Some(g-(α+1)*n,α+1)) g|>Seq.rev
let N2D n g=fst(Seq.foldBack(fun g (Σ,α)->(Σ+α*g,n*α)) g (0,1))
</syntaxhighlight>
===The Task===
<syntaxhighlight lang="fsharp">
let t0,t146,t10,t15=D2N -13 0,D2N -3 146,D2N -2 10,D2N -10 15
Seq.iter(fun n->Seq.iter(printf "%d ")n; printfn "")[t0;t146;t10;t15]
Seq.iter(printfn "%d ")[N2D -13 t0;N2D -3 t146;N2D -2 t10;N2D -10 t15]
</syntaxhighlight>
{{out}}
<pre>
0
2 1 1 0 2
1 1 1 1 0
1 9 5
0
146
10
15
</pre>
 
=={{header|Factor}}==
{{works with|Factor|0.99 2020-03-02}}
<syntaxhighlight lang="factor">USING: formatting fry kernel make math math.combinators
math.extras math.functions math.parser sequences ;
 
: /mod* ( x y -- z w )
[ /mod ] keep '[ [ 1 + ] dip _ abs + ] when-negative ;
 
: >nega ( n radix -- str )
[ '[ _ /mod* # ] until-zero ] "" make reverse ;
 
: nega> ( str radix -- n )
swap <reversed> [ ^ swap digit> * ] with map-index sum ;
 
: .round-trip ( n radix -- )
dupd [ >nega ] keep 2dup 2dup nega>
"%d_10 is %s_%d\n%s_%d is %d_10\n\n" printf ;
 
10 -2 146 -3 15 -10 [ .round-trip ] 2tri@</syntaxhighlight>
{{out}}
<pre>
10_10 is 11110_-2
11110_-2 is 10_10
 
146_10 is 21102_-3
21102_-3 is 146_10
 
15_10 is 195_-10
195_-10 is 15_10
</pre>
 
=={{header|FreeBASIC}}==
{{trans|VBA}}
<syntaxhighlight lang="vb">#define DIGITS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 
Dim cadena(63) As String
 
Function mod2(a As Long, b As Integer) As Long
Return a - (a \ b) * b
End Function
 
Function StrReverse(Byval text As String) As String
Dim As String text2 = text
Dim As Integer x, lt = Len(text)
For x = 0 To lt Shr 1 - 1
Swap text2[x], text2[lt - x - 1]
Next x
Return text2
End Function
 
Function EncodeNegativeBase(Byval n As Long, base_ As Integer) As String
Dim As Long Puntero, idx, rem_
Dim result As String
If base_ > -1 Or base_ < -62 Then
Return result
Else
If n = 0 Then
Return "0"
Else
Puntero = 0
Do While n <> 0
rem_ = mod2(n, base_)
n \= base_
If rem_ < 0 Then
n += 1
rem_ = rem_ - base_
End If
result &= Mid(DIGITS, rem_ + 1, 1)
Loop
End If
End If
Return StrReverse(result)
End Function
 
Function DecodeNegativeBase(ns As String, base_ As Integer) As Long
Dim As Long total, bb
Dim As Integer i, j
If base_ < -62 Or base_ > -1 Then Return 0
If Mid(ns, 1, 1) = "0" Or (Mid(ns, 1, 1) = "0" And Mid(ns, 2, 1) = "0") Then Return 0
i = Len(ns)
total = 0
bb = 1
Do While i >= 1
j = Instr(DIGITS, Mid(ns, i, 1)) - 1
total += j * bb
bb *= base_
i -= 1
Loop
Return total
End Function
 
Sub Driver(n As Long, b As Integer)
Dim As String ns = EncodeNegativeBase(n, b)
Print Str(n); " encoded in base "; b; " = "; ns
Dim As Long p = DecodeNegativeBase(ns, b)
Print ns; " decoded in base "; b; " ="; p
Print
End Sub
 
Driver 10, -2
Driver 146, -3
Driver 15, -10
Driver 118492, -62
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as VBA entry.</pre>
 
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 251 ⟶ 988:
fmt.Printf("%13s decoded in base %-3d = %d\n\n", ns, b, n)
}
}</langsyntaxhighlight>
 
{{out}}
Line 272 ⟶ 1,009:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.Char (chr, ord)
import Numeric (showIntAtBase)
 
Line 304 ⟶ 1,041:
printAtBase (-10) 15
printAtBase (-16) 107
printAtBase (-36) 41371458</langsyntaxhighlight>
 
{{out}}
Line 314 ⟶ 1,051:
1ab
perl6
</pre>
 
=={{header|J}}==
The j languages has builtin base and antibase verbs defined over the full complex realm. However, antibase produces negative digits. Additional coding required for antibase. Negative base works as is once the literal is converted back to a base 10 vector.
 
 
Model: python version.
Python and j divmod for negative divisor agree but for transposition.
 
<pre>
>>> # python divmod
>>> [divmod(i, -2) for i in (2, 3, 4, 5)]
[(-1, 0), (-2, -1), (-2, 0), (-3, -1)]
>>>
</pre>
 
<pre>
NB. j divmod
divmod =: <.@:%`(|~)`:0
2 3 4 5 divmod _2
_1 _2 _2 _3
0 _1 0 _1
</pre>
 
 
 
<pre>
NB. Use: BASE encode_neg_base INTEGER
NB. Output: literal
neg_antibase =: dyad define
b =. x
n =. y
if. 0 = n do. '0' return. end.
out =. i.0
while. n do.
'n rem' =. n divmod b
if. rem < 0 do.
n =. >: n
rem =. rem - b
end.
out =. out , rem
end.
(|. out) { _10 |. AlphaNum_j_
)
 
NB. use: BASE neg_base LITERAL
NB. output: integer
neg_base =: #. (_10 |. AlphaNum_j_)&i.
 
NB. neg_antibase test passes
_2 _3 _10 neg_antibase&> 10 146 15
11110
21102
195
 
NB. in j we would write the tautology
(":&.>11110 21102 195) -: _2 _3 _10 neg_antibase&.> 10 146 15
1
 
NB. expressive numeric notation
NB. we can write the numbers in arbitrary base
NB. The digit characters are limited to [0-9a-z]
 
_2b11110 _3b21102 _10b195
10 146 15
 
 
NB. neg_base test passes
 
_2 neg_base '11110'
10
 
_3 neg_base '21102'
146
_10 neg_base '195'
15
 
 
[ EXTRA_CREDIT =: _63 neg_base&> ;: 'J j apl APL Iverson'
19 45 139718 38136 1069471233985
_63 neg_antibase&> EXTRA_CREDIT
J
j
apl
APL
Iverson
</pre>
 
Line 319 ⟶ 1,145:
{{trans|Kotlin}}
{{works with|Java|9}}
<langsyntaxhighlight Javalang="java">import java.util.List;
import java.util.Map;
import java.util.Objects;
Line 371 ⟶ 1,197:
}
}
}</langsyntaxhighlight>
{{out}}
<pre> 10 encoded in base -2 = 11110
Line 388 ⟶ 1,214:
{{works with|jq|1.5}}
If your jq does not have `trunc/0` then use this:
<langsyntaxhighlight lang="jq">def trunc: if . >= 0 then floor else -(-(.)|trunc) end;</langsyntaxhighlight>
<langsyntaxhighlight lang="jq">def negbase($b):
if ($b >= 0) then error("negbase requires negative base")
elif . == 0 then "0"
Line 422 ⟶ 1,248:
;
 
test</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="jq">[true,true]
[true,true]
[true,true]</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">
function negbase(n, b)
if n == 0 return "0" end
Line 457 ⟶ 1,283:
decoded = invnegbase(encoded, base)
println("\nencode $num in base $base:\n-> expected: $rst\n-> resulted: $encoded\n-> decoded: $decoded")
end</langsyntaxhighlight>
 
{{out}}
Line 476 ⟶ 1,302:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
const val DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Line 518 ⟶ 1,344:
System.out.printf("%12s decoded in base %-3d = %d\n\n", ns, p.second, n)
}
}</langsyntaxhighlight>
 
{{out}}
Line 534 ⟶ 1,360:
Kotlin decoded in base -62 = -17596769891
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">EncodeBase[number_,base_]:=Module[{
out={},
rem,n=number,b=base
},
While[
n!=0,
{n,rem}={Floor[Divide[n,b]],Mod[n,b]};
If[
rem<0,
n+=1;
rem-=b
];
PrependTo[out,rem]
];
out
];
DecodeBase[list_,base_]:=Total[list*base^Range[Length[list]-1,0,-1]];
 
Print[EncodeNegBase[10,-2],"=",DecodeBase[EncodeNegBase[10,-2],-2]];
Print[EncodeNegBase[146,-3],"=",DecodeBase[EncodeNegBase[146,-3],-3]];
Print[EncodeNegBase[15,-10],"=",DecodeBase[EncodeNegBase[15,-10],-10]];</syntaxhighlight>
<pre>{1,1,1,1,0}=10
{2,1,1,0,2}=146
{1,9,5}=15</pre>
Extra Credit:
<syntaxhighlight lang="mathematica">DecodeBase[ToCharacterCode[$Version], -126](*ascii 1-byte encoding*)
DecodeBase[ToCharacterCode[$Version], -(2^16 - 1)](*2-byte encoding*)</syntaxhighlight>
<pre>805433247971592164648901981307140864173502418954511864100981464890629926293823767730118860531000284192172723837
1402171866107096793294662824351970913227448502019658754262020315290937172496459102043149157175108006798078612200544768242812932737034448604720533372980987964929785521161173764118702296122915325508945150191589743829011670147956776269027485433441427722106</pre>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE NegativeBase;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
 
CONST DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
TYPE String = ARRAY[0..63] OF CHAR;
 
PROCEDURE EncodeNegativeBase(n : LONGINT; base : LONGINT) : String;
PROCEDURE Mod(a,b : LONGINT) : LONGINT;
BEGIN
RETURN a - (a / b) * b
END Mod;
 
PROCEDURE Swap(VAR a,b : CHAR);
VAR t : CHAR;
BEGIN
t := a;
a := b;
b := t
END Swap;
VAR
ptr,idx : CARDINAL;
rem : LONGINT;
result : String;
BEGIN
IF (base > -1) OR (base < -62) THEN
RETURN result
ELSIF n = 0 THEN
result := "0"
ELSE
ptr := 0;
WHILE n # 0 DO
rem := Mod(n, base);
n := n / base;
IF rem < 0 THEN
INC(n);
rem := rem - base
END;
result[ptr] := DIGITS[rem];
INC(ptr);
END
END;
result[ptr] := 0C;
 
idx := 0;
DEC(ptr);
WHILE idx < ptr DO
Swap(result[idx], result[ptr]);
INC(idx);
DEC(ptr)
END;
 
RETURN result
END EncodeNegativeBase;
 
PROCEDURE DecodeNegativeBase(ns : String; base : LONGINT) : LONGINT;
VAR
total,bb,i,j : LONGINT;
BEGIN
IF (base < -62) OR (base > -1) THEN
RETURN 0
ELSIF (ns[0] = 0C) OR ((ns[0] = '0') AND (ns[1] = 0C)) THEN
RETURN 0
ELSE
FOR i:=0 TO HIGH(ns) DO
IF ns[i] = 0C THEN
BREAK
END
END;
DEC(i);
 
total := 0;
bb := 1;
WHILE i >= 0 DO
FOR j:=0 TO HIGH(DIGITS) DO
IF ns[i] = DIGITS[j] THEN
total := total + j * bb;
bb := bb * base;
BREAK
END
END;
DEC(i)
END;
END;
RETURN total
END DecodeNegativeBase;
 
PROCEDURE Driver(n,b : LONGINT);
VAR
ns,buf : String;
p : LONGINT;
BEGIN
ns := EncodeNegativeBase(n, b);
FormatString("%12l encoded in base %3l = %12s\n", buf, n, b, ns);
WriteString(buf);
 
p := DecodeNegativeBase(ns, b);
FormatString("%12s decoded in base %3l = %12l\n", buf, ns, b, p);
WriteString(buf);
 
WriteLn
END Driver;
 
BEGIN
Driver(10, -2);
Driver(146, -3);
Driver(15, -10);
Driver(-19425187910, -62);
 
ReadChar
END NegativeBase.</syntaxhighlight>
{{out}}
<pre> 10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
-19425187910 encoded in base -62 = Modula
Modula decoded in base -62 = -19425187910</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import algorithm, sugar, tables
 
const
Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Values = collect(initTable):
for i, c in Digits: {c: i} # Maps the digits to their values in base 10.
 
type Number = object
## Representation of a number in any base.
base: int
value: string
 
func toBase(n, base: int): Number =
## Convert an integer into a number in base 'base'.
assert base notin -1..1, "wrong value for base: " & $base
if n == 0: return Number(base: base, value: "0")
result.base = base
var n = n
while n != 0:
var m = n mod base
n = n div base
if m < 0:
inc m, abs(base)
inc n
result.value.add Digits[m]
result.value.reverse()
 
func `$`(n: Number): string =
## String representation of a number.
$n.value
 
func toInt(n: Number): int =
## Convert a number in some base into an integer in base 10.
for d in n.value:
result = n.base * result + Values[d]
 
 
when isMainModule:
 
proc process(n, base: int) =
let s = n.toBase(base)
echo "The value ", n, " is encoded in base ", base, " as: ", s
echo "and is decoded back in base 10 as: ", s.toInt
echo ""
 
process(10, -2)
process(146, -3)
process(15, -10)
 
const Nim = Number(base: -62, value: "Nim")
echo "The string “Nim” is decoded from base -62 to base 10 as: ", Nim.toInt</syntaxhighlight>
 
{{out}}
<pre>The value 10 is encoded in base -2 as: 11110
and is decoded back in base 10 as: 10
 
The value 146 is encoded in base -3 as: 21102
and is decoded back in base 10 as: 146
 
The value 15 is encoded in base -10 as: 195
and is decoded back in base 10 as: 15
 
The string “Nim” is decoded from base -62 to base 10 as: 85732</pre>
 
=={{header|ooRexx}}==
{{trans|REXX}}
<langsyntaxhighlight lang="oorexx">/* REXX ---------------------------------------------------------------
* Adapt for ooRexx (use of now invalid variable names)
* and make it work for base -63 (Algol example)
Line 595 ⟶ 1,642:
Else
r='ok'
Return r</langsyntaxhighlight>
{{out}}
<pre> 10 converted to base -2 ----> 11110 ok
Line 605 ⟶ 1,652:
-36492107981104 converted to base -63 ----> Algol 68 ok</pre>
 
=={{header|Perl 6}}==
{{libheader|ntheory}}
{{works with|Rakudo|2016.11}}
<syntaxhighlight lang="perl">use strict;
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.
use feature 'say';
use POSIX qw(floor);
use ntheory qw/fromdigits todigits/;
 
sub encode {
As a stretch goal, rather than implement something that can "Spell the name of the language with correct capitalization" (which is silly, trivial, and has absolutely '''''nothing''''' to do with negative base numbers,) we'll implement routines that correctly work with any Real number, not just integers.
my($n, $b) = @_;
my @out;
my $r = 0;
 
while ($n) {
The Real candidate has a 'precision' parameter, default -15, (15 places after the decimal point,) to limit the length of the fractional portion of the converted value. Change it if you need or want different precision. The Integer only routine is kept here as a multi-dispatch candidate since it is potentially much faster than the Real capable routine. The dispatcher will automatically use the most appropriate (fastest) routine.
$r = $n % $b;
 
$n = floor $n/$b;
Note that the parse-base routine will handle 'illegal' negative negative-base values without blowing up.
$n += 1, $r -= $b if $r < 0;
 
push @out, todigits($r, -$b) || 0;
<lang perl6>multi sub base ( Int $value is copy, Int $radix where -37 < * < -1) {
my $result;
while $value {
my $r = $value mod $radix;
$value div= $radix;
if $r < 0 {
$value++;
$r -= $radix
}
$result ~= $r.base(-$radix);
}
flipjoin $result'', ||reverse ~0@out;
}
 
sub decode {
multi sub base ( Real $num, Int $radix where -37 < * < -1, :$precision = -15 ) {
returnmy($s, '0'$b) unless= $num@_;
my $value total = $num0;
my $resulti = ''0;
for my $placec (reverse =split '', $s) 0;{
my $upper-bound = 1 /$total += (fromdigits($c, -$radixb) +* 1$b**$i);
my $lower-bound = $radix * $upper-boundi++;
 
$value = $num / $radix ** ++$place until $lower-bound <= $value < $upper-bound;
 
while ($value or $place > 0) and $place > $precision {
my $digit = ($radix * $value - $lower-bound).Int;
$value = $radix * $value - $digit;
$result ~= '.' unless $place or $result.contains: '.';
$result ~= $digit == -$radix ?? ($digit-1).base(-$radix)~'0' !! $digit.base(-$radix);
$place--
}
$resulttotal
}
 
say ' 10 in base -2: ', encode(10, -2);
multi sub parse-base (Str $str, Int $radix where -37 < * < -1) {
say ' 15 in base -10: ', encode(15, -10);
return -1 * $str.substr(1).&parse-base($radix) if $str.substr(0,1) eq '-';
say '146 in base -3: ', encode(146, -3);
my ($whole, $frac) = $str.split: '.';
say '';
my $fraction = 0;
say '11110 from base -2: ', decode("11110", -2);
$fraction = [+] $frac.comb.kv.map: { $^v.parse-base(-$radix) * $radix ** -($^k+1) } if $frac;
say '21102 from base -3: ', decode("21102", -3);
$fraction + [+] $whole.flip.comb.kv.map: { $^v.parse-base(-$radix) * $radix ** $^k }
say ' 195 from base -10: ', decode("195", -10);</syntaxhighlight>
}
{{out}}
<pre>
10 in base -2: 11110
15 in base -10: 195
146 in base -3: 21102
 
11110 from base -2: 10
# TESTING
21102 from base -3: 146
for <4 -4 0 -7 10 -2 146 -3 15 -10 -19 -10 107 -16
195 from base -10: 15</pre>
227.65625 -16 2.375 -4 -1.3e2 -8 41371457.268272761 -36> -> $v, $r {
my $nbase = $v.&base($r, :precision(-5));
printf "%20s.&base\(%3d\) = %-11s : %13s.&parse-base\(%3d\) = %s\n",
$v, $r, $nbase, "'$nbase'", $r, $nbase.&parse-base($r);
}
 
=={{header|Phix}}==
# 'Illegal' negative-base value
<!--<syntaxhighlight lang="phix">(phixonline)-->
say q| '-21'.&parse-base(-10) = |, '-21'.&parse-base(-10);</lang>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0123456789"</span><span style="color: #0000FF;">&</span>
<span style="color: #008000;">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span><span style="color: #0000FF;">&</span>
<span style="color: #008000;">"abcdefghijklmnopqrstuvwxyz"</span>
<span style="color: #008080;">type</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">b</span><span style="color: #0000FF;"><=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">>=-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">encodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">base</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trunc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">b</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">decodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">ns</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">base</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">bb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">>-</span><span style="color: #000000;">b</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008000;">"invalid digit"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">total</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">*</span><span style="color: #000000;">bb</span>
<span style="color: #000000;">bb</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">b</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">total</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- decimal, base, expected</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"11110"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">146</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"21102"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"195"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{-</span><span style="color: #000000;">5795577</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">62</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Phix"</span><span style="color: #0000FF;">}}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ns</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">encodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%9d in base %-3d is %6s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ns</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">nn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">decodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ok</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">=</span><span style="color: #000000;">e</span> <span style="color: #008080;">and</span> <span style="color: #000000;">nn</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" ????"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%9d &lt;--------------'%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">nn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ok</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
<pre> 4.&base( -4) = 130 : '130'.&parse-base( -4) = 4
10 in 0.&base( -7)2 = 0 : '0'.&parse-base( -7)is = 011110
10 <--------------'
10.&base( -2) = 11110 : '11110'.&parse-base( -2) = 10
146 in 146.&base( -3) = 21102is : '21102'.&parse-base( -3) = 146
146 <--------------'
15.&base(-10) = 195 : '195'.&parse-base(-10) = 15
15 in base -19.&base(-10) =is 21 : '21'.&parse-base(-10) = -19195
15 <--------------'
107.&base(-16) = 1AB : '1AB'.&parse-base(-16) = 107
-5795577 in base -62 is Phix
227.65625.&base(-16) = 124.68 : '124.68'.&parse-base(-16) = 227.65625
-5795577 <--------------'
2.375.&base( -4) = 3.32 : '3.32'.&parse-base( -4) = 2.375
</pre>
-1.3e2.&base( -8) = 1616 : '1616'.&parse-base( -8) = -130
41371457.268272761.&base(-36) = PERL6.ROCKS : 'PERL6.ROCKS'.&parse-base(-36) = 41371457.268272761
'-21'.&parse-base(-10) = 19</pre>
 
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">#!/bin/python
from __future__ import print_function
 
Line 725 ⟶ 1,809:
print (result)
if DecodeNegBase(result, -10) == 15: print ("Converted back to decimal")
else: print ("Error converting back to decimal")</langsyntaxhighlight>
 
{{out}}
Line 737 ⟶ 1,821:
195
Converted back to decimal</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ dup dip /mod
over iff
[ - dip 1+ ]
else drop ] is /mod+ ( n n --> n n )
 
[ over 0 = iff
[ 2drop $ "0" ]
done
temp put
$ "" swap
[ temp share /mod+
digit
rot join swap
dup 0 = until ]
drop
temp release ] is ->negabase$ ( n n --> $ )
 
[ over $ "0" = iff
[ 2drop 0 ]
done
temp put
0 swap
witheach
[ dip
[ temp share * ]
char->n + ]
temp release ] is negabase$-> ( $ n --> n )
 
10 dup echo say " -> "
-2 ->negabase$ dup echo$ say " -> "
-2 negabase$-> echo cr
146 dup echo say " -> "
-3 ->negabase$ dup echo$ say " -> "
-3 negabase$-> echo cr
15 dup echo say " -> "
-10 ->negabase$ dup echo$ say " -> "
-10 negabase$-> echo cr</syntaxhighlight>
 
{{out}}
 
<pre>10 -> 11110 -> 10
146 -> 21102 -> 146
15 -> 195 -> 15
</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define all-digits (string->list "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"))
Line 798 ⟶ 1,929:
 
(define-values (->hexadecimal hexadecimal->) (negabase-convertors 16))
(check-equal? (->hexadecimal 31) "1F"))</langsyntaxhighlight>
 
{{out}}
Line 806 ⟶ 1,937:
"195"
"Racket"</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
=== Explicit ===
{{works with|Rakudo|2016.11}}
Raku 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.
 
As a stretch goal, rather than implement something that can "Spell the name of the language with correct capitalization" (which is silly, trivial, and has absolutely '''''nothing''''' to do with negative base numbers,) we'll implement routines that correctly work with any Real number, not just integers.
 
The Real candidate has a 'precision' parameter, default -15, (15 places after the decimal point,) to limit the length of the fractional portion of the converted value. Change it if you need or want different precision. The Integer only routine is kept here as a multi-dispatch candidate since it is potentially much faster than the Real capable routine. The dispatcher will automatically use the most appropriate (fastest) routine.
 
Note that the parse-base routine will handle 'illegal' negative negative-base values without blowing up.
 
<syntaxhighlight lang="raku" line>multi sub base ( Int $value is copy, Int $radix where -37 < * < -1) {
my $result;
while $value {
my $r = $value mod $radix;
$value div= $radix;
if $r < 0 {
$value++;
$r -= $radix
}
$result ~= $r.base(-$radix);
}
flip $result || ~0;
}
 
multi sub base ( Real $num, Int $radix where -37 < * < -1, :$precision = -15 ) {
return '0' unless $num;
my $value = $num;
my $result = '';
my $place = 0;
my $upper-bound = 1 / (-$radix + 1);
my $lower-bound = $radix * $upper-bound;
 
$value = $num / $radix ** ++$place until $lower-bound <= $value < $upper-bound;
 
while ($value or $place > 0) and $place > $precision {
my $digit = ($radix * $value - $lower-bound).Int;
$value = $radix * $value - $digit;
$result ~= '.' unless $place or $result.contains: '.';
$result ~= $digit == -$radix ?? ($digit-1).base(-$radix)~'0' !! $digit.base(-$radix);
$place--
}
$result
}
 
multi sub parse-base (Str $str, Int $radix where -37 < * < -1) {
return -1 * $str.substr(1).&parse-base($radix) if $str.substr(0,1) eq '-';
my ($whole, $frac) = $str.split: '.';
my $fraction = 0;
$fraction = [+] $frac.comb.kv.map: { $^v.parse-base(-$radix) * $radix ** -($^k+1) } if $frac;
$fraction + [+] $whole.flip.comb.kv.map: { $^v.parse-base(-$radix) * $radix ** $^k }
}
 
# TESTING
for <4 -4 0 -7 10 -2 146 -3 15 -10 -19 -10 107 -16
227.65625 -16 2.375 -4 -1.3e2 -8 41371457.268272761 -36> -> $v, $r {
my $nbase = $v.&base($r, :precision(-5));
printf "%20s.&base\(%3d\) = %-11s : %13s.&parse-base\(%3d\) = %s\n",
$v, $r, $nbase, "'$nbase'", $r, $nbase.&parse-base($r);
}
 
# 'Illegal' negative-base value
say q| '-21'.&parse-base(-10) = |, '-21'.&parse-base(-10);</syntaxhighlight>
{{out}}
<pre> 4.&base( -4) = 130 : '130'.&parse-base( -4) = 4
0.&base( -7) = 0 : '0'.&parse-base( -7) = 0
10.&base( -2) = 11110 : '11110'.&parse-base( -2) = 10
146.&base( -3) = 21102 : '21102'.&parse-base( -3) = 146
15.&base(-10) = 195 : '195'.&parse-base(-10) = 15
-19.&base(-10) = 21 : '21'.&parse-base(-10) = -19
107.&base(-16) = 1AB : '1AB'.&parse-base(-16) = 107
227.65625.&base(-16) = 124.68 : '124.68'.&parse-base(-16) = 227.65625
2.375.&base( -4) = 3.32 : '3.32'.&parse-base( -4) = 2.375
-1.3e2.&base( -8) = 1616 : '1616'.&parse-base( -8) = -130
41371457.268272761.&base(-36) = PERL6.ROCKS : 'PERL6.ROCKS'.&parse-base(-36) = 41371457.268272761
'-21'.&parse-base(-10) = 19</pre>
 
=== Module ===
{{works with|Rakudo|2020.02}}
 
Using the module [https://modules.raku.org/search/?q=Base%3A%3AAny Base::Any] from the Raku ecosystem.
 
Does everything the explicit version does but also handles a '''much''' larger range of negative bases.
 
Doing pretty much the same tests as the explicit version.
 
<syntaxhighlight lang="raku" line>use Base::Any;
 
for < 4 -4 0 -7 10 -2 146 -3 15 -10 -19 -10 107 -16
227.65625 -16 2.375 -4 -1.3e2 -8 41371457.268272761 -36
-145115966751439403/3241792 -1184 > -> $v, $r {
my $nbase = $v.&to-base($r, :precision(-5));
printf "%21s.&to-base\(%5d\) = %-11s : %13s.&from-base\(%5d\) = %s\n",
+$v, $r, $nbase, "'$nbase'", $r, $nbase.&from-base($r);
}</syntaxhighlight>
{{out}}
<pre> 4.&to-base( -4) = 130 : '130'.&from-base( -4) = 4
0.&to-base( -7) = 0 : '0'.&from-base( -7) = 0
10.&to-base( -2) = 11110 : '11110'.&from-base( -2) = 10
146.&to-base( -3) = 21102 : '21102'.&from-base( -3) = 146
15.&to-base( -10) = 195 : '195'.&from-base( -10) = 15
-19.&to-base( -10) = 21 : '21'.&from-base( -10) = -19
107.&to-base( -16) = 1AB : '1AB'.&from-base( -16) = 107
227.65625.&to-base( -16) = 124.68 : '124.68'.&from-base( -16) = 227.65625
2.375.&to-base( -4) = 3.32 : '3.32'.&from-base( -4) = 2.375
-130.&to-base( -8) = 1616 : '1616'.&from-base( -8) = -130
41371457.268272761.&to-base( -36) = PERL6.ROCKS : 'PERL6.ROCKS'.&from-base( -36) = 41371457.268272761
-44764120200.01264825.&to-base(-1184) = Raku.FTW : 'Raku.FTW'.&from-base(-1184) = -44764120200.01264825</pre>
 
=={{header|REXX}}==
Both REXX versions use a type of &nbsp; ''assert'' &nbsp; (a function call of '''OK''') &nbsp; that converts the numbers in the
<br>negative base back to the original number in base ten &nbsp; (and issues an error message if not correct).
===versionhandles 1 (up to base -10)===
<langsyntaxhighlight lang="rexx">/*REXX pgm converts & displays a base ten integer to a negative base number (up to -10).*/
@=' converted to base '; numeric digits 300 /*be able to handle ginormous numbers. */
n= 10; b= -2; nb q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' nb q ok()
n= 146; b= -3; nb q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' nb q ok()
n= 15; b= -10; nb q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' nb q ok()
n= -15; b= -10; nb q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' nb q ok()
n= 0; b= -5; nb q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' nb q ok()
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
nBase: procedure; parse arg x,r; $= $= /*obtain args; $ is the integer result.*/
if r<-10 | r>-2 then do; say 'base' r "must be in range: -2 ───► -10"; exit 13; end
do while x\==0 /*keep processing while X isn't zero.*/
z= x // r; x=x%r x= x % r /*calculate remainder; calculate int ÷.*/
if z<0 then do; z= z - r /*subtract a negative R from Z ◄──┐ */
x= x + 1 /*bump X by one. │ */
end end /* Funny "add" ►───┘ */
$= z || $ /*prepend new digit (numeral) to result*/
end /*while*/
return word($ 0, 1) /*possibly adjust for a zero value. */
return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
ok: ?=; if pBase(nbq, b)\=n then ?= ' ◄──error in negative base calculation'; return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
pBase: procedure; parse arg x,r; p= 0; $=0 0 /*obtain args; $ is the integer result.*/
if r<-10 | r>-2 then do; say 'base' r "must be in range: -2 ───► -10"; exit 13; end
L=length(x); do j=Llength(x) by -1 for L length(x) /*process each of the numerals in X. */
$= $ + substr(x,j,1) * r ** p /*add value of a numeral to $ (result).*/
p= p + 1 p=p+1 /*bump the power by 1. */
end /*j*/ end /*j*/ /* [↓] process the number "bottom-up".*/
return $</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 849 ⟶ 2,090:
</pre>
 
===versionhandles 2 (up to base -71)===
This REXX version supports up to negative base &nbsp; '''─71''', &nbsp; but it may not be compatible to other programming examples
<br>because the symbols (glyphs or numerals) used herein may not be in the same exact order. &nbsp; The symbols represented
<br>in this REXX program should be able to represent &nbsp;almost ''any'' &nbsp; programming language used on Rosetta Code.
<langsyntaxhighlight lang="rexx">/*REXX pgm converts & displays a base ten integer to a negative base number (up to -71).*/
@=' converted to base '; numeric digits 300 /*be able to handle ginormous numbers. */
n= 10; b= -2; nb q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' nb q ok()
n= 146; b= -3; nb q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' nb q ok()
n= 15; b= -10; nb q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' nb q ok()
n= -15; b= -10; nb q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' nb q ok()
n= 0; b= -5; nb q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' nb q ok()
n=-6284695; b= -62; nb q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' nb q ok()
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
_Base: !='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz /*+-!éáµ' /*sym*/
parse arg $; m= length(!); L= length(x); p= 0
if r<-m | r>-2 then do; say 'base' r "must be in range: -2 ───► -"m; exit 13; end
return
Line 870 ⟶ 2,111:
nBase: procedure; parse arg x,r; call _Base /*get args; $ will be integer result. */
do while x\==0 /*keep processing while X isn't zero.*/
z=x // r; x= x %r r /*calculate remainder; calculate int ÷.*/
if z<0 then do; z= z -r r /*subtract a negative R from Z ◄──┐ */
x= x +1 1 /*bump X by one. │ */
end /* Funny "add" ►───┘ */
$=substr(!, z+1, 1)$ /*prepend the new numeral to the result*/
end /*while*/
if $=='' then return 0; return $ /*possibly adjust for a zero value. */
return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
ok: if pBase(nbq, b)\=n then return ' ◄──error in negative base calculation'; return ''
/*──────────────────────────────────────────────────────────────────────────────────────*/
pBase: procedure; parse arg x,r; call _Base 0 /*get args; $ will be integer result. */
do j=L by -1 for L /*process each of the numerals in X. */
v=pos( substr(x,j,1), !) - 1 /*use base R for the numeral's value.*/
$= $ + v * r**p; p= p + 1 /*add it to $ (result); bump power by 1*/
end /*j*/ /* [↑] process the number "bottom-up".*/
return $</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 895 ⟶ 2,136:
-6284695 converted to base -62 ────► Rexx
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Negative base numbers
 
negs = [[146,-3],[21102,-3],[10,-2],[11110,-2],[15,-10],[195,-10]]
for n = 1 to len(negs) step 2
enc = encodeNegBase(negs[n][1],negs[n][2])
encstr = showarray(enc)
dec = decodeNegBase(negs[n+1][1],negs[n+1][2])
see "" + negs[n][1] + " encoded in base " + negs[n][2] + " = " + encstr + nl
see "" + negs[n+1][1] + " decoded in base " + negs[n+1][2] + " = " + dec + nl
next
 
func encodeNegBase(n,b)
out = []
while n != 0
rem = (n%b)
if rem < 0
rem = rem - b
ok
n = ceil(n/b)
rem = fabs(rem)
add(out,rem)
end
out = reverse(out)
return out
 
func decodeNegBase(n,b)
out = 0
n = string(n)
for nr = len(n) to 1 step -1
out = out + n[nr]*pow(b,len(n)-nr)
next
return out
 
func showarray(vect)
svect = ""
for n = 1 to len(vect)
svect = svect + vect[n]
next
return svect
</syntaxhighlight>
{{out}}
<pre>
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
15 encoded in base -10 = 195
195 decoded in base -10 = 15
</pre>
=={{header|RPL}}==
{{trans||Python}}
« → base
« '''IF''' DUP NOT '''THEN''' →STR
'''ELSE'''
""
'''WHILE''' OVER '''REPEAT'''
base MOD LASTARG / FLOOR
'''IF''' OVER 0 < '''THEN'''
1 + SWAP
base -
'''ELSE''' SWAP '''END'''
ROT +
'''END''' SWAP DROP
» » '<span style="color:blue">→NEGB</span>' STO
« → nstr base
« 0
1 nstr SIZE '''FOR''' j
base *
nstr j DUP SUB STR→ +
'''NEXT'''
» » '<span style="color:blue">NEGB→</span>' STO
« { 10 -2 146 -3 15 -10 } → cases
« 1 cases SIZE '''FOR''' j
cases j GET cases j 1 + GET <span style="color:blue">→NEGB</span>
DUP cases j 1 + GET <span style="color:blue">NEGB→</span>
2 '''STEP'''
cases SIZE →LIST
» » '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
1: { "11110" 10 "21102" 146 "195" 15 }
</pre>
 
=={{header|Ruby}}==
{{trans|Julia}}
{{works with|Ruby|2.3}}
<syntaxhighlight lang="ruby">DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 
# convert a base 10 integer into a negative base value (as a string)
 
def negative_base_encode(n, b)
raise 'base out of range' if (b < -62) || (b > -2)
return '0' if n == 0
revdigs = []
while n != 0 do
n, r = n.divmod(b)
if r < 0
n += 1
r -= b
end
revdigs << r
end
return revdigs.reduce('') { |digstr, digit| DIGITS[digit] + digstr }
end
 
# convert a negative base value (as a string) into a base 10 integer
 
def negative_base_decode(n, b)
raise 'base out of range' if (b < -62) || (b > -2)
value = 0
n.reverse.each_char.with_index do |ch, inx|
value += DIGITS.index(ch) * b**inx
end
return value
end
 
# do the task
 
[ [10, -2], [146, -3], [15, -10], [0, -31], [-6221826, -62] ].each do |pair|
decimal, base = pair
encoded = negative_base_encode(decimal, base)
decoded = negative_base_decode(encoded, base)
puts("Enc: %8i base %-3i = %5s base %-3i Dec: %5s base %-3i = %8i base %-3i" %
[decimal, 10, encoded, base, encoded, base, decoded, 10])
end</syntaxhighlight>
{{out}}
<pre>Enc: 10 base 10 = 11110 base -2 Dec: 11110 base -2 = 10 base 10
Enc: 146 base 10 = 21102 base -3 Dec: 21102 base -3 = 146 base 10
Enc: 15 base 10 = 195 base -10 Dec: 195 base -10 = 15 base 10
Enc: 0 base 10 = 0 base -31 Dec: 0 base -31 = 0 base 10
Enc: -6221826 base 10 = Ruby base -62 Dec: Ruby base -62 = -6221826 base 10</pre>
 
=={{header|Rust}}==
{{trans|Go}}
<syntaxhighlight lang="rust">const DIGITS: [char;62] = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
 
fn main() {
let nums_and_bases: [(i64,i64);5] = [(10,-2),(146,-3),(15,-10),(-6222885,-62),(1488588316238,-62)];
 
for (n,b) in nums_and_bases.iter() {
let ns = encode_neg_base(*n, *b);
println!("{} encoded in base {} = {}", *n, *b, &ns);
let nn = decode_neg_base(&ns, *b);
println!("{} decoded in base {} = {}\n", &ns, *b, nn);
}
}
 
fn decode_neg_base(ns: &str, b: i64) -> i64 {
if b < -62 || b > -1 {
panic!("base must be between -62 and -1 inclusive")
}
if ns == "0" {
return 0
}
let mut total: i64 = 0;
let mut bb: i64 = 1;
for c in ns.chars().rev() {
total += (DIGITS.iter().position(|&d| d==c).unwrap() as i64) * bb;
bb *= b;
}
return total;
}
 
fn encode_neg_base(mut n: i64, b: i64) -> String {
if b < -62 || b > -1 {
panic!("base must be between -62 and -1 inclusive");
}
if n == 0 {
return "0".to_string();
}
let mut out = String::new();
while n != 0 {
let mut rem = n % b;
n /= b;
if rem < 0 {
n+=1;
rem -= b;
}
out.push(DIGITS[rem as usize]);
}
return out.chars().rev().collect();
}</syntaxhighlight>
 
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">object NegativeBase {
val digits = ('0' to '9') ++ ('a' to 'z') ++ ('A' to 'Z')
Line 919 ⟶ 2,349:
}._1
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="scala">def testConversion(b: Int)(n: Int, s: String): Unit = {
println(s"$n in base -$b = ${NegativeBase.intToStr(n, b)}")
println(s"$s from base -$b = ${NegativeBase.strToInt(s, b)}")
Line 929 ⟶ 2,359:
testConversion(3)(146, "21102")
testConversion(10)(15, "195")
testConversion(62)(795099356, "Scala")</langsyntaxhighlight>
 
{{out}}
Line 942 ⟶ 2,372:
Scala from base -62 = 795099356</pre>
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const string: DIGITS is "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
const func string: encodeNegativeBase (in var integer: number, in integer: base) is func
result
var string: encoded is "";
local
var integer: remainder is 0;
begin
if base < -62 or base > -1 then
raise RANGE_ERROR;
elsif number = 0 then
encoded := "0";
else
while number <> 0 do
remainder := number rem base;
number := number div base;
if remainder < 0 then
incr(number);
remainder -:= base;
end if;
encoded &:= DIGITS[succ(remainder)];
end while;
encoded := reverse(encoded);
end if;
end func;
 
const func integer: decodeNegativeBase (in string: encoded, in integer: base) is func
result
var integer: decoded is 0;
local
var integer: factor is 1;
var integer: index is 0;
var integer: digit is 0;
begin
if base < -62 or base > -1 then
raise RANGE_ERROR;
elsif encoded = "0" then
decoded := 0;
else
for index range length(encoded) downto 1 do
digit := pred(pos(DIGITS, encoded[index]));
if digit = -1 then
raise RANGE_ERROR;
else
decoded +:= digit * factor;
factor *:= base;
end if;
end for;
end if;
end func;
 
const proc: doCheck (in integer: number, in integer: base) is func
local
var string: encoded is "";
var integer: decoded is 0;
begin
encoded := encodeNegativeBase(number, base);
writeln(number lpad 10 <& " encoded in base " <& base lpad 3 <& " = " <& encoded);
decoded := decodeNegativeBase(encoded, base);
writeln(encoded lpad 10 <& " decoded in base " <& base lpad 3 <& " = " <& decoded);
end func;
 
const proc: main is func
begin
doCheck(10, -2);
doCheck(146, -3);
doCheck(15, -10);
doCheck(404355637, -62);
end func;</syntaxhighlight>
 
{{out}}
<pre>
10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
15 encoded in base -10 = 195
195 decoded in base -10 = 15
404355637 encoded in base -62 = Seed7
Seed7 decoded in base -62 = 404355637
</pre>
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
{{trans|Python}}
<langsyntaxhighlight lang="ruby">func EncodeNegBase(Num n, Num b { .~~ (-36 .. -2) }) {
var out = []
var r = 0
Line 982 ⟶ 2,496:
# Extra
say ("25334424 in base -31: ", EncodeNegBase(25334424, -31))
say ("sidef from base -31: ", DecodeNegBase("sidef", -31))</langsyntaxhighlight>
{{out}}
<pre>
Line 995 ⟶ 2,509:
25334424 in base -31: sidef
sidef from base -31: 25334424
</pre>
 
=={{header|VBA}}==
{{trans|Modula-2}}
<syntaxhighlight lang="vb">Const DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Dim Str(63) As String
Private Function mod2(a As Long, b As Integer) As Long
mod2 = a - (a \ b) * b
End Function
Private Function swap(a As String, b As String)
Dim t As String
t = a
a = b
b = t
End Function
Private Function EncodeNegativeBase(ByVal n As Long, base As Integer) As String
Dim ptr, idx As Long
Dim rem_ As Long
Dim result As String
If base > -1 Or base < -62 Then
EncodeNegativeBase = result
Else
If n = 0 Then
EncodeNegativeBase = "0"
Else
ptr = 0
Do While n <> 0
rem_ = mod2(n, base)
n = n \ base
If rem_ < 0 Then
n = n + 1
rem_ = rem_ - base
End If
result = result & Mid(DIGITS, rem_ + 1, 1)
Loop
End If
End If
EncodeNegativeBase = StrReverse(result)
End Function
Private Function DecodeNegativeBase(ns As String, base As Integer) As Long
Dim total As Long, bb As Long
Dim i As Integer, j As Integer
If base < -62 Or base > -1 Then DecodeNegativeBase = 0
If Mid(ns, 1, 1) = 0 Or (Mid(ns, 1, 1) = "0" And Mid(ns, 2, 1) = 0) Then DecodeNegativeBase = 0
i = Len(ns)
total = 0
bb = 1
Do While i >= 1
j = InStr(1, DIGITS, Mid(ns, i, 1), vbTextCompare) - 1
total = total + j * bb
bb = bb * base
i = i - 1
Loop
DecodeNegativeBase = total
End Function
Private Sub Driver(n As Long, b As Integer)
Dim ns As String
Dim p As Long
ns = EncodeNegativeBase(n, b)
Debug.Print CStr(n); " encoded in base "; b; " = "; ns
p = DecodeNegativeBase(ns, b)
Debug.Print ns; " decoded in base "; b; " = "; p
Debug.Print
End Sub
Public Sub main()
Driver 10, -2
Driver 146, -3
Driver 15, -10
Driver 118492, -62
End Sub</syntaxhighlight>
{{out}}
<pre>10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
118492 encoded in base -62 = VBA
VBA decoded in base -62 = 118492 </pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 
var encodeNegBase = Fn.new { |n, b|
if (b < -62 || b > -1) Fiber.abort("Base must be between -1 and -62")
if (n == 0) return "0"
var out = ""
while (n != 0) {
var rem = n % b
n = (n/b).truncate
if (rem < 0) {
n = n + 1
rem = rem -b
}
out = out + digits[rem]
}
return out[-1..0]
}
 
var decodeNegBase = Fn.new { |ns, b|
if (b < -62 || b > -1) Fiber.abort("Base must be between -1 and -62")
if (ns == "0") return 0
var total = 0
var bb = 1
for (c in ns[-1..0]) {
total = total + digits.indexOf(c)*bb
bb = bb * b
}
return total
}
 
var nbl = [ [10, -2], [146, -3], [15, -10], [-7425195, -62] ]
for (p in nbl) {
var ns = encodeNegBase.call(p[0], p[1])
Fmt.print("$8d encoded in base $-3d = $s", p[0], p[1], ns)
var n = decodeNegBase.call(ns, p[1])
Fmt.print("$8s decoded in base $-3d = $d\n", ns, p[1], n)
}</syntaxhighlight>
 
{{out}}
<pre>
10 encoded in base -2 = 11110
11110 decoded in base -2 = 10
 
146 encoded in base -3 = 21102
21102 decoded in base -3 = 146
 
15 encoded in base -10 = 195
195 decoded in base -10 = 15
 
-7425195 encoded in base -62 = Wren
Wren decoded in base -62 = -7425195
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn toNBase(n,radix){
var [const] cs=[0..9].chain(["a".."z"]).pump(String); //"0123456789abcd..z"
_assert_(-37 < radix < -1,"invalid radix");
Line 1,012 ⟶ 2,665:
fcn toInt(str,radix){ // the toInt(radix) method radix is 2..36
str.reduce('wrap(s,d,rdx){ s*radix + d.toInt(rdx); },0,radix.abs());
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">ns:=T( T(10,-2), T(146,-3), T(15,-10), T(107,-16), T(41371458,-36), T(44661,-36) );
results:=ns.pump(List,Void.Xplode,toNBase);
foreach nb,r in (ns.zip(results)){
_,b:=nb;
println("%10d.base(%3d) = \"%s\" --> %d".fmt(nb.xplode(),r,toInt(r,b)));
}</langsyntaxhighlight>
{{out}}
<pre>
1,150

edits