RosettaCodeData/Task/Formatted-numeric-output/Bc/formatted-numeric-output-1.bc

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. */
}