⎕FMT – Format Data

Contents

  1. Introduction
  2. Format Phrases
    1. Notes
    2. Alphabetic Format (Aw)
    3. Exponential Format (Ew.p)
    4. Fixed Point Format (Fw.p)
    5. Graphic Format (G<picture>)
    6. Integer Format (Iw)
    7. Tab To Column (Tcolumn)
    8. Variable Format (Vw.p)
    9. Move Cursor (Xoffset)
    10. Text Fields
  3. Modifiers
    1. Justification (←, =, or →)
    2. Base / Blank if Zero (B[radix])
    3. Commas (C[spacing])
    4. Scale a Number (Kscale)
    5. Left Justify (L)
    6. Negative Number Prefix Text (M<text>)
    7. Negative Number Suffix Text (N<text>)
    8. Replace Value With Text (O[cinu][value][<text>])
    9. Positive Number Prefix Text (P<text>)
    10. Positive Number Suffix Text (Q<text>)
    11. Repeated Background Text (R<text>)
    12. Substitute (S<old new…>)
    13. Zero Fill (Z)
    14. Zero Fill Exponent (Ze)
  4. Repetition Counts
  5. Grouping With Parentheses
  6. Complex Numbers
  7. Invalid Numbers

Introduction

⎕FMT formats data in an easily readable form, producing a character matrix as a result.

The left argument of dyadic format is a character scalar or vector consisting of one or more format phrases, separated by commas. Most format phrases describe how to format one column of the result. But the number of format phrases doesn't have to match the number of columns in the result. Processing starts with the leftmost format phrase and proceeds toward the right. If there are fewer format phrases than columns to be formatted, the sequence of phrases will be used repeatedly until formatting is completed. On the other hand, if more format phrases are provided than are required, the extra format phrases on the right end will simply be ignored.

There are some format phrases whose purpose is to insert text into the result or move to a different column in the result. These have no effect on the processing of the right argument.

Note that the format phrases are case-sensitive. This allows a wider range of options with less chance of ambiguity.

The right argument may be a simple array or a vector of simple arrays.

Format Phrases

Phrase TypeNameMeaning
AwAlphabeticFormat a character
Ew.pExponentialFormat a number in scientific notation
Fw.pFixed PointFormat a number in conventional notation
G<picture>GraphicRound to an integer, then insert digits into the picture
IwIntegerRound to an integer, then display
TcTabTab to column c (right edge if c is omitted)
Vw.pVariableUse E or F format, depending on size of number
XsSpaceMove s columns left (if negative) or right
<text>TextInsert text at the current position

Key

Notes

For E, F, and V, the precision defaults to 6 if it is not specified.

If the field width is 0, the corresponding column of data is omitted from the result.

If the field width is omitted, the minimum necessary field width is used.

If an error occurs, such as the formatted value not fitting in the specified field width, or a format phrase being applied to the wrong data type (e.g. 'F' being applied to a character or 'A' to a number), the field is filled with asterisks. The S modifier (see below) can be used to select a different character to represent an error.

The columns of data to be formatted do not all have to be the same length. Shorter columns will be padded with blank rows, as necessary, during formatting.

Alphabetic Format (Aw)

A single character or column of characters is formatted in a field of the specified width (or width 1 if no width is specified). To format a matrix of characters, you will need one A format phrase for each column. For this purpose, repetition counts (see below) are often convenient.

Exponential Format (Ew.p)

One digit will be displayed before the decimal point and p digits will be displayed after it. Note that the last five columns out of the total field width are reserved for the letter 'E', the sign of the exponent (if it is negative), and up to three digits for the exponent itself. The exponent will be formatted using the minimum necessary number of digits, left-justified, with unused columns on the right being filled with blanks (or the background text if the R modifier is used). For example:

      '|',('E12.4' ⎕FMT 1234567 5243 ¯5165551212 0.000012345678),'|'
| 1.2346E6   |
| 5.2430E3   |
|¯5.1656E9   |
| 1.2346E¯5  |

      '|',('R<⋆∘>E12.4' ⎕FMT 1234567 5243 ¯5165551212 0.000012345678),'|'
|⋆1.2346E6∘⋆∘|
|⋆5.2430E3∘⋆∘|
|¯5.1656E9∘⋆∘|
|⋆1.2346E¯5⋆∘|

If for some reason you want the numbers to line up at the right edge, you can use the Ze modifier (see below) to pad the exponents with leading zeros:

      '|',('ZeE12.4' ⎕FMT 1234567 5243 ¯5165551212 0.000012345678),'|'
| 1.2346E0006|
| 5.2430E0003|
|¯5.1656E0009|
| 1.2346E¯005|

If you want to display numbers using the standard minus sign (−) rather than the APL high minus (¯) you can use the S modifier. Unlike the M modifier this will set the minus sign character for both the mantissa and the exponent. For example:

      'S<¯->E12.2' ⎕FMT ¯0.0000635
  -6.35E-5  

      'M<(>N<)>E12.2' ⎕FMT ¯0.0000635
 (6.35E¯5  )

      'M<(>N<)>ZeE12.2' ⎕FMT ¯0.0000635
 (6.35E¯005)

Fixed Point Format (Fw.p)

The precision p is the number of digits to follow the decimal point. If the precision is zero, no decimal point will be displayed.

Graphic Format (G<picture>)

The number is rounded to the nearest integer and formatted as indicated by the picture. The picture is a sequence of characters where '9' or 'Z' indicates a position where a digit is to be inserted into the picture. Any characters preceding the first '9' or 'Z' are known as the leading text. Digits are inserted into the picture proceeding from right to left, starting with the last digit in the integer.

In addition to '9' and 'Z', '?' also has a special meaning, as described below. If you want to use any of these characters in the picture itself, you can use the S modifier (see below) to reassign their meanings to other characters. This modifier may also be used to change the character used as a negative sign.

If the number to be formatted (along with its sign if the number is negative) does not fit in the picture, or the number is too large to fit in an APL integer, the picture is replaced with a row of asterisks.

'9' always displays a digit, adding leading zeros if necessary.

      'G<9999-99-99 99:99:99>' ⎕FMT 20221225170922 3240714091223
2022-12-25 17:09:22
0324-07-14 09:12:23

'Z' inserts a digit if there are any left, otherwise it inserts a negative sign (if needed) or a blank instead of a leading zero. In the latter case, the portion of the picture to the left of the 'Z', aside from any leading text, will be replaced with blanks.

'?' (the stop character) is not copied to the output. If no digit other than a leading zero would be displayed by a '9' to the left of the stop character, the portion of the picture to the left of that character is replaced with blanks, including leading text. For example:

      'G<(ZZZ) 999-9999>'  ⎕FMT 1234567 5243 5165551212 12345678
(     123-4567
(     000-5243
(516) 555-1212
(  1) 234-5678

      'G<(ZZZ)? 999-9999>'  ⎕FMT 1234567 5243 5165551212 12345678
      123-4567
      000-5243
(516) 555-1212
(  1) 234-5678

Integer Format (Iw)

The number is rounded to the nearest integer and displayed. The precision, if specified, is ignored. Use the Z modifier (see below) if you want leading zeros instead of blanks.

Tab To Column (Tcolumn)

The cursor is moved to the specified column. The leftmost column is 1. If the cursor is moved to the right of the rightmost column, the necessary number of blanks is inserted.

Variable Format (Vw.p)

Fixed-point format is generally easier to read than exponential format, as the magnitude of the number is immediately apparent from the number of digits to the left of the decimal point or the number of leading zeros to the right of the decimal point. However, should an unexpectedly large number cause an F format phrase to overflow, the result is an uninformative row of asterisks. It is a nuisance to have to set the field width to a large number just in case a calculation produces a number that was larger than expected, and it might be necessary to limit the width of a field to allow a report to be printed out if desired. So it is a useful to have a format phrase that will display numbers in fixed-point format where possible, but use exponential format if the number is too large to fit in a field of given size.

For precision p and field width w, the variable format phrase uses fixed point (F) format if p > exponent ≥ ¯4, exponential (E) format otherwise. Note that p digits will be displayed to the right of the decimal point. If you specify w you should probably set it to at least p + 8 to allow room for a leading sign, a decimal point, and the exponent.

Note that because exponents are normally displayed with the minimum number of digits required, numbers displayed in scientific notation might not be right-justified. This can give the output a ragged appearance. Using the Ze modifier (see below) to zero-fill the exponents can fix this problem at the expense of making exponents slightly harder to read. For example:

      'V' ⎕FMT 10⋆¯8+⍳15
1.000000E¯7  
1.000000E¯6  
1.000000E¯5  
1.000000E¯4  
1.000000E¯3  
1.000000E¯2  
     0.100000
     1.000000
    10.000000
   100.000000
  1000.000000
 10000.000000
1.000000E5   
1.000000E6   
1.000000E7   

      'ZeV' ⎕FMT 10⋆¯8+⍳15
1.000000E¯007
1.000000E¯006
1.000000E¯005
1.000000E¯004
1.000000E¯003
1.000000E¯002
     0.100000
     1.000000
    10.000000
   100.000000
  1000.000000
 10000.000000
1.000000E0005
1.000000E0006
1.000000E0007

Move Cursor (Xoffset)

The offset is the number of columns to move the cursor. Negative offsets move the cursor to the left, positive offsets move it to the right. Attempts to move the cursor to the left of the first column will move it to the first column instead. If the cursor is moved to the right of the rightmost column, the necessary number of blanks is inserted.

If the offset is omitted, it defaults to 1.

Text Fields

Text provided as part of a format phrase may be enclosed in any of the following pairs of characters:

<>        ''    //        
    ¨¨    ""    \\        ||

for example, G⊂(999) 999-9999⊃.

Modifiers

Modifiers change the way in which a value is formatted. Most modifiers apply only to certain types of format phrases.

ModifierUse ForMeaning
anyLeft-justify
=anyCenter
anyRight-justify (default)
BanyReplace zeroes with blanks
BbaseGIDisplay numbers in a specified radix
CspacingEFIVInsert commas to group digits
KscaleEFGIVScale the numbers by a power of the radix
LanyLeft-justify (same as '←')
M<text>EFIVInsert text to left of negative value
N<text>EFIVInsert text to right of negative value
Onum<text>EFGIVReplace a number with text
Occhar<text>AReplace a character with text
Oi<text>EFIVReplace an infinite value with text
On<text>EFGIVReplace Not-a-Number with text
Ounum<text>AReplace a character with text (num = ⎕UCS char)
P<text>EFIVInsert text to left of nonnegative value
Q<text>EFIVInsert text to right of nonnegative value
R<text>AEFIVRepeated background fill
S<pairs>anySubstitute characters
ZEFIVZero fill
ZeEZero fill the exponent

Justification (←, =, or →)

'←' left-justifies the text in the field.

'=' centers the text in the field.

'→' right-justifies the text in the field (this is the default justification).

Base / Blank if Zero (B[radix])

This modifier allows you to display a value in any radix from 2 to 16 when using a 'G' or 'I' format phrase.

For backwards compatability with earlier versions of ⎕FMT, a B with no number following it causes zeros to be replaced with blanks, the same as an O with no replacement value or replacement text following it.

Commas (C[spacing])

The spacing is the number of digits between commas. If this is omitted it defaults to 3. When using a radix other than 10 to display a value, it may be more useful to set the comma spacing to some other value, such as 4 or 8.

Scale a Number (Kscale)

The number is multiplied by radixscale before being formatted. The default scale is 0 (no scaling). The radix defaults to 10, but may be altered by use of the B modifier.

Left Justify (L)

The text is left-justified in the field, just as for modifier.

Negative Number Prefix Text (M<text>)

This text is prepended to negative numbers. It must fit in the field for the format phrase, if the field width is specified. If neither the M modifier nor the N modifier is specified, this text defaults to the negative sign character. This is done after the S modifier, if any, has been processed.

Negative Number Suffix Text (N<text>)

This text is appended to negative numbers. It must fit in the field for the format phrase, if the field width is specified.

Replace Value With Text (O[cinu][value][<text>])

If the value n is omitted, we replace zeros. If the text is omitted, we replace the value with blanks. So O by itself will replace zeros with blanks.

For Oc, value is the character to be replaced.

For Oi, value is omitted. Infinities will be replaced with the specified text.

For On, value is omitted. Not-a-number (NaN) values will be replaced with the specified text.

For Ou, value is the value of ⎕UCS c, where c is the character to be replaced. The 'u' stands for Unicode.

Warning: in some cases it may be necessary to specify the replacement text or use whitespace to avoid ambiguity. For example, in O5.5E12.7 the replacement value would be read as 5.5E12, leading to a syntax error when the decimal point was encountered. This could be rewritten more clearly as O5.5 E12.7 or O5.5<>E12.7.

Replacements are performed before scaling by the K modifier. So if you use K and O together, be careful to specify the correct value to be replaced.

Positive Number Prefix Text (P<text>)

This text is prepended to positive numbers. It must fit in the field for the format phrase, if the field width is specified.

Positive Number Suffix Text (Q<text>)

This text is appended to positive numbers. It must fit in the field for the format phrase, if the field width is specified.

Repeated Background Text (R<text>)

The specified text is repeated as many times as necessary to replace leading or trailing blanks.

Substitute (S<old new…>)

This replaces some of the standard characters used in formatting with new characters. One or more pairs of characters is specified. The first character in each pair is the character to be replaced. The second is the character to replace it with.

The first character in each pair is compared with the characters in the original, default character set, shown in the first column of the table below, in order to determine which character to replace. Therefore, expressions such as S/,..,/ may be used without confusion.

Replacing the negative sign changes the character used for both the mantissa and exponent when scientific notation is used, whereas the modifier M<-> only changes the mantissa sign character.

The characters that may be replaced are:

CharacterUse ForMeaning
9GDigit
ZGDigit, or blank if zero
allOverflow / error fill
.EFVDecimal point
,CGroup (e.g. thousands) separator
_FGIVLoss of precision indicator
0EFGIVLeading zero fill character
¯EFGIVNegative sign
EEVExponent prefix
?GStop character

For example: S<9#Z_>G<_# Boskonians spotted by the Z9M9Z>

Zero Fill (Z)

Zeros are used in place of leading blanks. If you want to replace both leading and trailing blanks with zeros, use the R modifier instead.

Zero Fill Exponent (Ze)

When used with the E format phrase, this causes the exponent to be padded with leading zeros so the last digit of the exponent appears at the rightmost edge of the field.

Repetition Counts

A format phrase may be preceded by a positive integer to indicate that it is to be repeated that number of times. For example, 3F12.7 indicates that the format phrase F12.7 is to be applied to the next three columns of data. The repetition count must not be zero.

The repetition count precedes the first modifier, if any.

Grouping With Parentheses

Parentheses may be used to group a set of format phrases so that a repetition count or a specified set of modifiers can be applied to the group as a whole. Modifiers specified for a group become the defaults for every phrase in the group but can be overridden by modifiers specified for individual phrases within the group.

For example, 2(E15.5,CF7.2) is equivalent to E15.5,CF7.2,E15.5,CF7.2. S<,..,>(F7.2,E12.4,3F10.6) swaps commas and decimal points for every format phrase in the group (see the S modifier above).

      A
0        274.3 ¯12.8 1700   98.6    42  89.5
0.00001 ¯678    99   ¯102.7 23.321 212 ¯12.3456789

      '2S<¯->(2F.2,I4),F.4' ⎕FMT A
0.00  274.30 -13 1700.00 98.60  42  89.5000
0.00 -678.00  99 -102.70 23.32 212 ¯12.3457

Complex Numbers

Any column of data containing a complex number generates two columns of output and therefore consumes two format phrases. The first column of output contains the real part of each number in the data column, the second contains the imaginary part. For any non-complex elements in the column of data the imaginary part is zero. These zeros can be suppressed with the O or B modifier if desired.

For example:

      'P<(>M<(>E14.6,P<, >M<, >Q<)>N<)>F6.1' ⎕FMT 307.2J4.6
(3.072000E2   , 4.6)

      'ZeP<(>M<(>E14.6,P<, >M<, >Q<)>N<)>F6.1' ⎕FMT 307.2J4.6
(3.072000E0002, 4.6)

      'F12.5' ⎕FMT 12.7 123 6J5 9.27J¯12 ¯4.12
    12.70000   0.000
   123.00000   0.000
     6.00000   5.000
     9.27000 ¯12.000
    ¯4.12000   0.000

      'F.2,I' ⎕FMT 12.7 123 6J5 9.27J¯12 ¯4.12
 12.70   0
123.00   0
  6.00   5
  9.27 ¯12
 ¯4.12   0

      'F,I' ⎕FMT 12.7 123 6J5 9.27J¯12 ¯4.12
 12.700000   0
123.000000   0
  6.000000   5
  9.270000 ¯12
 ¯4.120000   0

     'F,OI' ⎕FMT 12.7 123 6J5 9.27J¯12 ¯4.12
 12.700000    
123.000000    
  6.000000   5
  9.270000 ¯12
 ¯4.120000    

Possible Future Extensions

The procedure used for handling complex numbers should be easy to apply to rational numbers stored as a separate numerator and denominator. It could also be extended to handle other multi-part numbers such as quaternions or octonions.

Invalid Numbers

The IEEE 754 standard for floating-point arithmetic allows for two special cases that require special handling by ⎕FMT:

The O modifier may be used to specify replacement text for both infinity (Oi) and NaN (On). But note that the comparisons for O are performed before scaling:

      'Oi<inf>K1234F' ⎕FMT 0 274.3 ¯12.8 1e1234
  ?
  ∞
 ¯∞
inf