X-Git-Url: http://git.shiar.net/sheet.git/blobdiff_plain/1107366d212418d8f8a6a80c54115387816ef2a2..HEAD:/base.plp diff --git a/base.plp b/base.plp index ad6961b..a68a71f 100644 --- a/base.plp +++ b/base.plp @@ -1,8 +1,8 @@ <(common.inc.plp)><: Html({ - title => 'fractions', - version => 'v1.0', + title => 'number bases', + version => '1.2', description => [ "Cheat sheets summarising various software programs and standards.", ], @@ -12,48 +12,166 @@ Html({ 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', +); :> -

Fractions

+

Number bases

- +

Radix economy

+
+<: +sub showcolhead { + print ''; + my @spans; + $spans[ $_ > 10 ]++ for @_; + print "" for @spans; + print ''; +} + +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 '
'; + for (@_) { + print '', $_ < 36 ? $char[$_] : $char[35].'+'.$char[$_ - 35]; + print " ($_)" for join(', ', + $RADIXNAME{$_} // (), + $_ >= 10 ? "base$_" : (), + ) || (); + } + say '
⍳', $max; + for my $radix (@morecols) { + printf '%.1f', + sum(map { radix_economy($_, $radix) } 1 .. $max) / $max; + } +} +:>
+ +

Reciprocal fractions (n⁻¹)

+ <: use Math::BigFloat; -my @cols = (2, 6, 8, 9, 10, 12, 16, 18, 60); -print '' if $n % 8 == 1; print ''; print '
'; -print '', $_ 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) = ''; + $check .= ''; + last ADD_DIGITS; + } + } + } + printf '%s', $class && qq( class="$class"), $out; +} + +showcolhead(@cols); + +for my $n (2 .. $count) { + print '
', $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 '%s', $class && qq( class="$class"), $out; + showfrac(scalar Math::BigFloat->new(1)->bdiv($n, $accuracy+1), $radix); } -# \x{305} + say ''; } + :>
+
+ +

Duplication (2ⁿ)

+ +<: +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 ''; + next; + } + print ''; + print '
', $n; + for my $radix (@cols) { + print '', showint(2 ** $n, $radix); + } + say '', { + 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} // ''; +} + +:>