78 lines
1.9 KiB
Plaintext
78 lines
1.9 KiB
Plaintext
/*
|
|
* Print number n, using at least c characters.
|
|
*
|
|
* Different from normal, this function:
|
|
* 1. Uses the current ibase (not the obase) to print the number.
|
|
* 2. Prunes "0" digits from the right, so p(1.500, 1) prints "1.5".
|
|
* 3. Pads "0" digits to the left, so p(-1.5, 6) prints "-001.5".
|
|
* 4. Never prints a newline.
|
|
*
|
|
* Use an assignment, as t = p(1.5, 1), to discard the return value
|
|
* from this function so that bc not prints the return value.
|
|
*/
|
|
define p(n, c) {
|
|
auto d, d[], f, f[], i, m, r, s, v
|
|
s = scale /* Save original scale. */
|
|
|
|
if (n < 0) {
|
|
"-" /* Print negative sign. */
|
|
c -= 1
|
|
n = -n /* Remove negative sign from n. */
|
|
}
|
|
|
|
/* d[] takes digits before the radix point. */
|
|
scale = 0
|
|
for (m = n / 1; m != 0; m /= 10) d[d++] = m % 10
|
|
|
|
/* f[] takes digits after the radix point. */
|
|
r = n - (n / 1) /* r is these digits. */
|
|
scale = scale(n)
|
|
f = -1 /* f counts the digits of r. */
|
|
for (m = r + 1; m != 0; m /= 10) f += 1
|
|
scale = 0
|
|
r = r * (10 ^ f) / 1 /* Remove radix point from r. */
|
|
if (r != 0) {
|
|
while (r % 10 == 0) { /* Prune digits. */
|
|
f -= 1
|
|
r /= 10
|
|
}
|
|
for (i = 0; i < f; i++) {
|
|
f[i] = r % 10
|
|
r /= 10
|
|
}
|
|
}
|
|
|
|
/* Pad "0" digits to reach c characters. */
|
|
c -= d
|
|
if (f > 0) c -= 1 + f
|
|
for (1; c > 0; c--) "0" /* Print "0". */
|
|
|
|
/* i = index, m = maximum index, r = digit to print. */
|
|
m = d + f
|
|
for (i = 1; i <= m; i++) {
|
|
if (i <= d) r = d[d - i]
|
|
if (i > d) r = f[m - i]
|
|
if (i == d + 1) "." /* Print radix point. */
|
|
|
|
v = 0
|
|
if (r == v++) "0" /* Print digit. */
|
|
if (r == v++) "1"
|
|
if (r == v++) "2" /* r == 2 might not work, */
|
|
if (r == v++) "3" /* unless ibase is ten. */
|
|
if (r == v++) "4"
|
|
if (r == v++) "5"
|
|
if (r == v++) "6"
|
|
if (r == v++) "7"
|
|
if (r == v++) "8"
|
|
if (r == v++) "9"
|
|
if (r == v++) "A"
|
|
if (r == v++) "B"
|
|
if (r == v++) "C"
|
|
if (r == v++) "D"
|
|
if (r == v++) "E"
|
|
if (r == v++) "F"
|
|
}
|
|
|
|
scale = s /* Restore original scale. */
|
|
}
|