f34f36e8580a4a25f00567040bdd381f1a99d993
[sheet.git] / base.plp
1 <(common.inc.plp)><:
2
3 Html({
4         title => 'number bases',
5         version => 'v1.1',
6         description => [
7                 "Cheat sheets summarising various software programs and standards.",
8         ],
9         keywords => [qw'
10                 sheet cheat reference software overview summary help keyboard map unicode
11         '],
12         stylesheet => [qw'light dark circus mono red'],
13 });
14
15 my @cols = (2, 6, 8, 9, 10, 12, 16, 18, 20);
16 my @morecols = (2, 3, 4, 6, 8, 9, 10, 12, 16, 18, 20, 24, 32, 36, 64);
17 my @char = (0..9, 'A'..'Z', 'a'..'z');
18 :>
19 <h1>Number bases</h1>
20
21 <h2>Fractions</h2>
22 <table>
23 <:
24 print '<tr><th>';
25 print '<th>', $_ for @cols;
26
27 use Math::BigFloat;
28
29 my $count = 40;
30 my $places = $count<<1;
31
32 sub showfrac {
33         my ($num, $radix) = @_;
34
35         my $out = '';
36         my $class = '';
37         my $zeros = 0;
38
39 ADD_DIGITS:
40         for my $place (1 .. $places) {
41                 # add a digit in requested base (left shift)
42                 $out .= $char[ $num->blsft(1, $radix) ];
43                 $num->bmod(1) or do {
44                         # no remaining fractional part
45                         $class = $out eq '1' ? 'l5' : $place == 1 ? 'l4' : 'l3';
46                         last;
47                 };
48                 $zeros++ if $out =~ /^0+$/;
49
50                 for my $check ($zeros .. length($out)>>1) {
51                         if (substr($out, -$check) eq substr($out, -$check*2, $check)) {
52                                 $class = $check == 1 ? 'l2' : 'l1';
53                                 substr($out, -$check) = '';
54                                 substr($out, -$check, 0) = '<span style="text-decoration:overline">';
55                                 $check .= '</span>';
56                                 last ADD_DIGITS;
57                         }
58                 }
59         }
60         printf '<td%s style="text-align:left">%s', $class && qq( class="$class"), $out;
61 }
62
63 for my $n (2 .. $count) {
64         print '<tr>';
65         print '<th>', $n;
66         for my $radix (@cols) {
67                 my $accuracy = int($places * log($radix) / log(10));
68                 Math::BigFloat->accuracy($accuracy);
69                 showfrac(scalar Math::BigFloat->new(1)->bdiv($n, $accuracy+1), $radix);
70         }
71 }
72
73 :></table>
74
75 <hr>
76
77 <h2>Duplication</h2>
78 <table>
79 <:
80 use 5.010;
81 sub showint {
82         my ($int, $radix) = @_;
83         my @digits;
84         while ($int >= 1) {
85                 push @digits, $char[$int % $radix];
86                 $int /= $radix;
87         }
88         splice @digits, 3 * $_, 0, '&nbsp;' for reverse 1 .. @digits/3;
89         return join '', reverse @digits;
90 }
91
92 @cols = grep { not $_ ~~ [2,8,16] } @cols, 36;
93 print '<tr><th>';
94 print '<th>', $_ for @cols;
95
96 for my $n (3 .. 16, 18, 20, 24, 30, 32, 36, 40, 48, 50, 60, 64) {
97         print '<tr>';
98         print '<th>', $n;
99         for my $radix (@cols) {
100                 print '<td style="text-align:right">', showint(2 ** $n, $radix);
101         }
102         print '<th>', {
103                  4 => 'nibble',
104                  8 => 'octet',
105                 16 => '2o',
106                 24 => '3o',
107                 32 => '4o',
108                 40 => '5o, Tebi',
109                 48 => '6o',
110                 64 => 'o²',
111                 10 => 'kibi',
112                 20 => 'Mebi',
113                 30 => 'Gibi',
114                 50 => 'Pebi',
115                 60 => 'Exbi',
116                 70 => 'Zebi',
117                 80 => 'Yobi',
118         }->{$n} // '';
119 }
120
121 :></table>