Want to use numbers that are represented in something other than base 10? That’s no problem in Perl 6. Some languages throw you a bone with binary, octal, or hexadecimal conversions, but what if you want base 17? Or, better yet, base 36?
First, for Real numbers (or, non-complex numbers), I have the base command:
$ perl6 > 137.base(2) 10001001 > 137.base(8) 211 > 137.base(16) 89 > 137.base(36) 3T
I can go up to base-36 because that’s how many digits and Latin letters the method uses. Those convert number types to strings.
I can go the other way too. The :DIGIT(string)
syntax converts strings to numbers:
> :2('10001001') 137 > :8('211') 137 > :16('89') 137
These assume that the string is a number represented that the radix after the colon. These return a Perl 6 number, which you can display in any base that you like.
From there I can make some one-liners to convert bases. I’ve done this for Perl 5, and now I have them for Perl 6:
alias o2b="perl6 -e 'say sprintf q/:2(%b)/, :8(@*ARGS.shift)'" alias o2d="perl6 -e 'say sprintf q/:10(%d)/, :8(@*ARGS.shift)'" alias o2h="perl6 -e 'say sprintf q/:16(%x)/, :8(@*ARGS.shift)'" alias d2b="perl6 -e 'say sprintf q/:2(%b)/, @*ARGS.shift'" alias d2o="perl6 -e 'say sprintf q/:8(%d)/, @*ARGS.shift'" alias d2h="perl6 -e 'say sprintf q/:16(%x)/, @*ARGS.shift'" alias h2b="perl6 -e 'say sprintf q/:2(%b)/, :16(@*ARGS.shift)'" alias h2o="perl6 -e 'say sprintf q/:8(%o)/, :16(@*ARGS.shift)'" alias h2d="perl6 -e 'say sprintf q/:10(%d)/, :16(@*ARGS.shift)'"
If you give your aliases a parameter that is not a number, or not a number of the right base, you may get back a LTA error message which looks confusing and also seemss fixable by changing a few characters of the program.
$ alias o2b=”perl6 -e ‘say sprintf q/:2(%b)/, :8(@*ARGS.shift)'”
$ o2b 99
Directive b not applicable for type Failure
in any at /home/ron/.rakudobrew/moar-nom/install/share/perl6/runtime/CORE.setting.moarvm line 1
What appears to be happening is that :8() is returning type Failure which does not throw an exception until evaluation.
If we evaluate earlier with +:8() then:
$ alias o2b=”perl6 -e ‘say sprintf q/:2(%b)/, +:8(@*ARGS.shift)'”
$ o2b 99
Cannot convert string to number: base-8 number must begin with valid digits or ‘.’ in ‘:8’ (indicated by ⏏)
in block at -e line 1
Actually thrown at:
in block at -e line 1
$ o2b abc
Cannot convert string to number: base-8 number must begin with valid digits or ‘.’ in ‘:8’ (indicated by ⏏)
…
$ o2b 42
:2(100010)
Which looks like better handling with just a little extra effort.
In the case of d2[boh] one may need to use +:10(@*ARGS.shift).
Very nice! I was wondering about that but I had to move on to another task. Thanks!
The much simpler way to write that is as:
Instead of that ugly sprintf concoction.
.parse-base also handles negative numbers, unlike the :16() radix literal syntax.
My 2016.11 claims that
parse-base
is not a known method.