<(common.inc.plp)><:
Html({
- title => 'fractions',
- version => 'v1.0',
+ title => 'number bases',
+ version => '1.2',
description => [
"Cheat sheets summarising various software programs and standards.",
],
stylesheet => [qw'light dark circus mono red'],
});
+my @cols = (2, 6, 8, 9, 10, 12, 16, 18, 20);
+my @morecols = (2 .. 6, 8, 9, 10, 12, 16, 18, 20, 24, 32, 36, 64);
+my @char = (0..9, 'A'..'Z', 'a'..'z');
+my %RADIXNAME = (
+ 2 => 'binary',
+ 3 => 'ternary',
+ #4 => 'quaternary',
+ #5 => 'quinary',
+ 6 => 'senary',
+ 8 => 'octal',
+ #9 => 'nonary',
+ 10 => 'decimal',
+ 12 => 'dozenal', # duodecimal
+ 16 => 'hexadecimal',
+ 20 => 'vigesimal',
+ #36 => 'double-senary',
+ 60 => 'sexagesimal',
+ #64 => 'double-octal',
+);
:>
-<h1>Fractions</h1>
+<h1>Number bases</h1>
-<table>
+<h2>Radix economy</h2>
+<table class=mapped>
+<:
+sub showcolhead {
+ print '<col>';
+ my @spans;
+ $spans[ $_ > 10 ]++ for @_;
+ print "<colgroup span=$_>" for @spans;
+ print '<thead><tr><th>';
+ for (@_) {
+ print '<th>', $_ < 36 ? $char[$_] : $char[35].'+'.$char[$_ - 35];
+ print " <small>($_)</small>" for join(', ',
+ $RADIXNAME{$_} // (),
+ $_ >= 10 ? "base$_" : (),
+ ) || ();
+ }
+ say '</thead>';
+}
+
+sub radix_economy {
+ my ($val, $radix) = @_;
+ return $radix * int(log($val) / log($radix) + 1);
+}
+
+use List::Util 'sum';
+
+showcolhead(@morecols);
+
+for my $max (100, 255, 1024) {
+ print '<tr><th>⍳', $max;
+ for my $radix (@morecols) {
+ printf '<td style="text-align:right">%.1f',
+ sum(map { radix_economy($_, $radix) } 1 .. $max) / $max;
+ }
+}
+:></table>
+
+<h2>Reciprocal fractions (n⁻¹)</h2>
+<table class=mapped>
<:
use Math::BigFloat;
-my @cols = (2, 6, 8, 9, 10, 12, 16, 18, 60);
-print '<tr><th>';
-print '<th>', $_ for @cols;
+my $count = 40;
+my $places = $count<<1;
-my @char = (0..9, 'A'..'Z', 'a'..'z');
-my $places = 48;
+sub showfrac {
+ my ($num, $radix) = @_;
+
+ my $out = '';
+ my $class = '';
+ my $zeros = 0;
+
+ADD_DIGITS:
+ for my $place (1 .. $places) {
+ # add a digit in requested base (left shift)
+ $out .= $char[ $num->blsft(1, $radix) ];
+ $num->bmod(1) or do {
+ # no remaining fractional part
+ $class = $out eq '1' ? 'l5' : $place == 1 ? 'l4' : 'l3';
+ last;
+ };
+ $zeros++ if $out =~ /^0+$/;
-for my $n (2 .. 25) {
+ for my $check ($zeros .. length($out)>>1) {
+ if (substr($out, -$check) eq substr($out, -$check*2, $check)) {
+ $class = $check == 1 ? 'l2' : 'l1';
+ substr($out, -$check) = '';
+ substr($out, -$check, 0) = '<span style="text-decoration:overline">';
+ $check .= '</span>';
+ last ADD_DIGITS;
+ }
+ }
+ }
+ printf '<td%s style="text-align:left">%s', $class && qq( class="$class"), $out;
+}
+
+showcolhead(@cols);
+
+for my $n (2 .. $count) {
+ print '<tbody>' if $n % 8 == 1;
print '<tr>';
print '<th>', $n;
for my $radix (@cols) {
my $accuracy = int($places * log($radix) / log(10));
Math::BigFloat->accuracy($accuracy);
- my $frac = Math::BigFloat->new(1)->bdiv($n, $accuracy+1);
- my $out = '';
- my $class = '';
-ADD_DIGITS:
- for my $place (1 .. $places) {
- $out .= $char[ $frac->blsft(1, $radix) ];
- $frac->bmod(1) or do {
- $class = $n == $radix ? 'l5' : $place == 1 ? 'l4' : 'l3';
- last;
- };
- for my $check (log($n)/log($radix) .. length($out)>>1) {
- if ($out =~ /[^0]/ and substr($out, -$check) eq substr($out, -$check*2, $check)) {
- $class = $check == 1 ? 'l2' : 'l1';
- substr($out, -$check) = '';
- substr($out, -$check, 0) = '(';
- last ADD_DIGITS;
- }
- }
- }
- printf '<td%s>%s', $class && qq( class="$class"), $out;
+ showfrac(scalar Math::BigFloat->new(1)->bdiv($n, $accuracy+1), $radix);
}
-# \x{305}
+ say '';
}
+
:></table>
+<hr>
+
+<h2>Duplication (2ⁿ)</h2>
+<table class=mapped>
+<:
+sub showint {
+ my ($int, $radix) = @_;
+ my @digits;
+ while ($int >= 1) {
+ push @digits, $char[$int % $radix];
+ $int /= $radix;
+ }
+ splice @digits, 3 * $_, 0, ' ' for reverse 1 .. @digits/3;
+ return join '', reverse @digits;
+}
+
+@cols = grep { not $_ ~~ [2,8,16] } @cols, 36;
+showcolhead(@cols);
+
+for my $n (0, 3 .. 16, 0, 18, 20, 24, 30, 32, 36, 40, 48, 50, 60, 64) {
+ if (!$n) {
+ print '<tbody>';
+ next;
+ }
+ print '<tr>';
+ print '<th>', $n;
+ for my $radix (@cols) {
+ print '<td style="text-align:right">', showint(2 ** $n, $radix);
+ }
+ say '<th>', {
+ 4 => 'nibble',
+ 8 => 'octet',
+ 16 => '2o',
+ 24 => '3o',
+ 32 => '4o',
+ 40 => '5o, Tebi',
+ 48 => '6o',
+ 64 => 'o²',
+ 10 => 'kibi',
+ 20 => 'Mebi',
+ 30 => 'Gibi',
+ 50 => 'Pebi',
+ 60 => 'Exbi',
+ 70 => 'Zebi',
+ 80 => 'Yobi',
+ }->{$n} // '';
+}
+
+:></table>