Next: , Previous: , Up: Enhanced Number Types   [Contents][Index]


63.6 New Output Formatting Features

ENT provides a number of new format specifiers:

Both ‘%B’ and ‘%C’ are actually rewrites to ‘%Z%+Z’ and ‘%F%+F’ respectively with the argument arg rewritten to (real-part arg) (imaginary-part arg). Flags are passed on to at least the real part specifier.

On the other hand, we have tried to seamlessly integrate the new specifiers along with the ordinary ones. Any number object is coerced to the integers if ‘%d’ or ‘%Z’ is used, if that is possible (see Coercion). Besides, the base converters work on any number in two steps, too: firstly, coerce to the integers, secondly convert to another base.

Time for examples. Here we demonstrate the equivalence of ‘%d’ and ‘%Z’ if used with big integers as arguments.

(format "%d" (factorial 20))
     ⇒ "2432902008176640000"
(format "%30d" (factorial 20))
     ⇒ "           2432902008176640000""
(format "%.30d" (factorial 20))
     ⇒ "000000000002432902008176640000"
(format "%Z" (factorial 20))
     ⇒ "2432902008176640000"
(format "%30Z" (factorial 20))
     ⇒ "           2432902008176640000""
(format "%.30Z" (factorial 20))
     ⇒ "000000000002432902008176640000"

Now we look at the coercion facilities:

(format "%d" (exp 1))
     ⇒ "3"
(format "%Z" pi)
     ⇒ "3"
(format "%d" 2/3)
     ⇒ "0"
(format "%Z" 4+3i)
     ⇒ Wrong type argument: comparablep, 4+3i

Let us have a quick glance at the specifiers ‘%f’, ‘%F’ and ‘%R’. The most obvious difference is their way to format precision flags, especially how they do precision rounding.

The specifier ‘%f’ performs a mathematically correct rounding, whereas ‘%F’ cuts the precision, that is it truncates the result at the given place.

(format "%f" (exp 1))
     ⇒ "2.718282"
(format "%.2f" (exp 1))
     ⇒ "2.72"
(format "%+.2f" (exp 1))
     ⇒ "+2.72"
(format "%F" (exp 1))
     ⇒ "2.718281828459045235360287471352662497759"
(format "%.2F" (exp 1))
     ⇒ "2.71"
(format "%+.2f" (exp 1))
     ⇒ "+2.71"

Indeed, ‘%R’ is rewritten to either ‘%f’ or ‘%F’, depending on whether read-real-as is set to 'float or 'bigf or 'bigfr, thusly precision rounding is performed the way of the rewritten specifier.

read-real-as
     ⇒ 'float
(format "%R" (exp 1))
     ⇒ "2.718282"
(format "%.2R" (exp 1))
     ⇒ "2.72"
(let ((read-real-as 'bigfr))
  (format "%R" (exp 1)))
     ⇒ "2.718281828459045235360287471352662497759"
(let ((read-real-as 'bigfr))
  (format "%.2R" (exp 1)))
     ⇒ "2.71"

A special exception of the float formatting rule are indefinite numbers (we like it to call them indefinite symbols since they are not numbers). These are +infinite, -infinite and not-a-number. Except the total width flag all of the special flags are ignored in their format specification.

(format "%F" +infinity)
     ⇒ "+infinity"
(format "%F" -infinity)
     ⇒ "-infinity"
(format "%F" not-a-number)
     ⇒ "not-a-number"
(format "%+F" +infinity)
     ⇒ "+infinity"
(format "% F" -infinity)
     ⇒ "-infinity"
(format "%.10F" not-a-number)
     ⇒ "not-a-number"

and compare to:

(format "%12F" +infinity)
     ⇒ "   +infinity"
(format "%-12F" -infinity)
     ⇒ "-infinity   "
(format "%20F" not-a-number)
     ⇒ "        not-a-number"

The coercion to rational quotients (and their output formatting) is straightforward. It suffers from the impossibility to sanely coerce from floating point numbers, see Coercion.

The precision flag, in contrast, has no effect on rational quotients. It is generally deprecated to prepend leading zeroes to the numerator of a fraction.

If the quotient can be cancelled it is done so, and the formatted output uses this cancelled fraction. If the quotient cancels to a rational integer, i.e. if the denominator is 1, the formatted output shows the integer equivalent of the fraction. Note that even in that situation the precision flag has no effect.

(format "%Q" 2)
     ⇒ "2"
(format "%Q" 4/2)
     ⇒ "2"
(format "%4Q" 4/2)
     ⇒ "   2"
(format "%.4Q" 4/2)
     ⇒ "2"
(format "%Q" 2/3)
     ⇒ "2/3"
(format "%5Q" 2/3)
     ⇒ "  2/3"
(format "%5.5Q" 2/3)
     ⇒ "  2/3"
(format "%+Q" 2/3)
     ⇒ "+2/3"
(format "% Q" 2/3)
     ⇒ " 2/3"
(format "%Q" 1.5)
     ⇒ "3/2"
(format "%Q" 0.66666)
     ⇒ "3002369727582815/4503599627370496"

Finally we have a detailed look at the rewriting technique of complex and Gaussian numbers.

(format "%B" 2+i)
     ⇒ "2+1i"
(format "%Z%+Zi" (real-part 2+i) (imaginary-part 2+i))
     ⇒ "2+1i"
(format "%C" 1+i)
     ⇒ "1.00000000000000+1.00000000000000i"
(format "%F%+Fi" (real-part 1+i) (imaginary-part 1+i))
     ⇒ "1.00000000000000+1.00000000000000i"

Flag characters as well as padding and precision flags are passed to the rewritten specifiers with the following exception, the space and unary plus flags are not passed to the second rewritten specifier, instead the second rewritten specifier is always flagged with the unary plus.

(format "%.4C" 1+i)
     ⇒ "1.0000+1.0000i"
(format "% B" 2+i)
     ⇒ " 2+1i"
(format "%+.2C" 2+3i)
     ⇒ "+2.00+3.00i"
(format "%10.4C" 1+i)
     ⇒ "    1.0000   +1.0000i"
(format "%+10.4B" 1+i)
     ⇒ "     +0001     +0001i"
(format "%-10.2C" 0+0i)
     ⇒ "0.00      +0.00     i"

Next: , Previous: , Up: Enhanced Number Types   [Contents][Index]