Commit | Line | Data |
---|---|---|
8340f87c BJ |
1 | .NH |
2 | Number Registers and Arithmetic | |
3 | .PP | |
4 | .UL troff | |
5 | has a facility for doing arithmetic, | |
6 | and for defining and using variables with numeric values, | |
7 | called | |
8 | .ul | |
9 | number registers. | |
10 | Number registers, like strings and macros, can be useful in setting up a document | |
11 | so it is easy to change later. | |
12 | And of course they serve for any sort of arithmetic computation. | |
13 | .PP | |
14 | Like strings, number registers have one or two character names. | |
15 | They are set by the | |
16 | .BD .nr | |
17 | command, | |
18 | and are referenced anywhere by | |
19 | .BD \enx | |
20 | (one character name) or | |
21 | .BD \en(xy | |
22 | (two character name). | |
23 | .PP | |
24 | There are quite a few pre-defined number registers maintained by | |
25 | .UL troff , | |
26 | among them | |
27 | .BD % | |
28 | for the current page number; | |
29 | .BD nl | |
30 | for the current vertical position on the page; | |
31 | .BD dy , | |
32 | .BD mo | |
33 | and | |
34 | .BD yr | |
35 | for the current day, month and year; and | |
36 | .BD .s | |
37 | and | |
38 | .BD .f | |
39 | for the current size and font. | |
40 | (The font is a number from 1 to 4.) | |
41 | Any of these can be used in computations like any other register, | |
42 | but some, like | |
43 | .BD .s | |
44 | and | |
45 | .BD .f , | |
46 | cannot be changed with | |
47 | .BD .nr . | |
48 | .PP | |
49 | As an example of the use of number registers, | |
50 | in the | |
51 | .BD \-ms | |
52 | macro package [4], | |
53 | most significant parameters are defined in terms of the values | |
54 | of a handful of number registers. | |
55 | These include the point size for text, the vertical spacing, | |
56 | and the line and title lengths. | |
57 | To set the point size and vertical spacing for the following paragraphs, for example, a user may say | |
58 | .P1 | |
59 | ^nr PS 9 | |
60 | ^nr VS 11 | |
61 | .P2 | |
62 | The paragraph macro | |
63 | .BD .PP | |
64 | is defined (roughly) as follows: | |
65 | .P1 | |
66 | .ta 1i | |
67 | ^de PP | |
68 | ^ps \e\en(PS \e" reset size | |
69 | ^vs \e\en(VSp \e" spacing | |
70 | ^ft R \e" font | |
71 | ^sp 0.5v \e" half a line | |
72 | ^ti +3m | |
73 | ^^ | |
74 | .P2 | |
75 | This sets the font to Roman and the point size and line spacing | |
76 | to whatever values are stored in the number registers | |
77 | .BD PS | |
78 | and | |
79 | .BD VS . | |
80 | .PP | |
81 | Why are there two backslashes? | |
82 | This is the eternal problem of how to quote a quote. | |
83 | When | |
84 | .UL troff | |
85 | originally reads the macro definition, | |
86 | it peels off one backslash | |
87 | to see what's coming next. | |
88 | To ensure that another is left in the definition when the | |
89 | macro is | |
90 | .ul | |
91 | used, | |
92 | we have to put in two backslashes in the definition. | |
93 | If only one backslash is used, | |
94 | point size and vertical spacing will be frozen at the time the macro | |
95 | is defined, not when it is used. | |
96 | .PP | |
97 | Protecting by an extra layer of backslashes | |
98 | is only needed for | |
99 | .BD \en , | |
100 | .BD \e* , | |
101 | .BD \e$ | |
102 | (which we haven't come to yet), | |
103 | and | |
104 | .BD \e | |
105 | itself. | |
106 | Things like | |
107 | .BD \es , | |
108 | .BD \ef , | |
109 | .BD \eh , | |
110 | .BD \ev , | |
111 | and so on do not need an extra backslash, | |
112 | since they are converted by | |
113 | .UL troff | |
114 | to an internal code immediately upon being seen. | |
115 | .WS | |
116 | .PP | |
117 | Arithmetic expressions can appear anywhere that | |
118 | a number is expected. | |
119 | As a trivial example, | |
120 | .P1 | |
121 | ^nr PS \e\en(PS\-2 | |
122 | .P2 | |
123 | decrements PS by 2. | |
124 | Expressions can use the arithmetic operators +, \-, *, /, % (mod), | |
125 | the relational operators >, >=, <, <=, =, and != (not equal), | |
126 | and parentheses. | |
127 | .PP | |
128 | Although the arithmetic we have done so far | |
129 | has been straightforward, | |
130 | more complicated things are somewhat tricky. | |
131 | First, | |
132 | number registers hold only integers. | |
133 | .UL troff | |
134 | arithmetic uses truncating integer division, just like Fortran. | |
135 | Second, in the absence of parentheses, | |
136 | evaluation is done left-to-right | |
137 | without any operator precedence | |
138 | (including relational operators). | |
139 | Thus | |
140 | .P1 | |
141 | 7*\-4+3/13 | |
142 | .P2 | |
143 | becomes `\-1'. | |
144 | Number registers can occur anywhere in an expression, | |
145 | and so can scale indicators like | |
146 | .BD p , | |
147 | .BD i , | |
148 | .BD m , | |
149 | and so on (but no spaces). | |
150 | Although integer division causes truncation, | |
151 | each number and its scale indicator is converted | |
152 | to machine units (1/432 inch) before any arithmetic is done, | |
153 | so | |
154 | 1i/2u | |
155 | evaluates to | |
156 | 0.5i | |
157 | correctly. | |
158 | .PP | |
159 | The scale indicator | |
160 | .BD u | |
161 | often has to appear | |
162 | when you wouldn't expect it _ | |
163 | in particular, when arithmetic is being done | |
164 | in a context that implies horizontal or vertical dimensions. | |
165 | For example, | |
166 | .P1 | |
167 | ^ll 7/2i | |
168 | .P2 | |
169 | would seem obvious enough _ | |
170 | 3\(12 inches. | |
171 | Sorry. | |
172 | Remember that the default units for horizontal parameters like | |
173 | .BD .ll | |
174 | are ems. | |
175 | That's really `7 ems / 2 inches', | |
176 | and when translated into machine units, it becomes zero. | |
177 | How about | |
178 | .P1 | |
179 | ^ll 7i/2 | |
180 | .P2 | |
181 | Sorry, still no good _ | |
182 | the `2' is `2 ems', so `7i/2' is small, | |
183 | although not zero. | |
184 | You | |
185 | .ul | |
186 | must | |
187 | use | |
188 | .P1 | |
189 | ^ll 7i/2u | |
190 | .P2 | |
191 | So again, a safe rule is to | |
192 | attach a scale indicator to every number, | |
193 | even constants. | |
194 | .PP | |
195 | For arithmetic done within a | |
196 | .BD .nr | |
197 | command, | |
198 | there is no implication of horizontal or vertical dimension, | |
199 | so the default units are `units', | |
200 | and 7i/2 and 7i/2u | |
201 | mean the same thing. | |
202 | Thus | |
203 | .P1 | |
204 | ^nr ll 7i/2 | |
205 | ^ll \e\en(llu | |
206 | .P2 | |
207 | does just what you want, | |
208 | so long as you | |
209 | don't forget the | |
210 | .BD u | |
211 | on the | |
212 | .BD .ll | |
213 | command. |