Hi Francesco, At 2025-02-21T16:19:25+0100, Francesco Ariis wrote: > can I format/scale numbers when interpolating them?
Not without arithmetic, as far as I know. > Long explanation follows. > > While writing a minimal reproducible example for this list, > I found myself typing: > > Line length is set to: > .nr calc \n[.l]/1c > \n[calc] > > Notice how, to interpolate line length in centimetres: I picked > an auxiliary register, scaled the number to centimetres, and then > displayed it. Right. I think this is the most straightforward approach that exists; arbitrary numeric expressions cannot be directly interpolated--there's no escape sequence for that. (If we wanted one, I notice that `\=` is available.) So what one does instead is assign the numeric expression of interest to a register and then interpolate that. > I am sure I am not the first one wanting to format number output. > Is there a way to — say — \n[my-id]c to have a register interpolated > in a specific scaling unit? No. GNU troff has as an extension a scaling operator `;`, but it's used for the opposite purpose: application of scaling units to quantities on their way to register values, which are always in basic units, subdivided ("scaled") points, or dimensionless. What one might call an "outbound" scaling operator does not exist in the language. I further observe that a loss of precision threatens. $ cat EXPERIMENTS/unit-conversion.groff .nf .nr basic-units-per-cm 1c There are \n[basic-units-per-cm] basic units per centimeter. The line length is \n[.l] basic units. .nr line-length-in-cm \n[.l]/1c The line length is \n[line-length-in-cm]\~cm. $ groff -a EXPERIMENTS/unit-conversion.groff <beginning of page> There are 28346 basic units per centimeter. The line length is 468000 basic units. The line length is 16 cm. That's pretty coarse. The default line length on the PostScript device is 6.5 inches (468000u), and at 2.54cm per inch, the true line length is closer to 16.51cm. The usual remedy in this situations is to use scaled integer arithmetic, multipling all quantities of interest by a factor (often a power of ten) sufficient to preserve the desired precision through division operations. Here's a crude example. $ cat EXPERIMENTS/unit-conversion2.groff .nf .nr basic-units-per-cm 1c .nr scale-factor 1000u \" 10, 100, or 1000; 10000 overflows We're subdividing the centimeter by \n[scale-factor] for arithmetic. .nr basic-units-per-subcm 1c*\n[scale-factor] There are \n[basic-units-per-subcm] basic units per subdivided centimeter. The line length is \n[.l] basic units. .nr line-length-in-subcm \n[.l]*\n[scale-factor]/\n[basic-units-per-cm] The line length is \n[line-length-in-subcm] in subdivided centimeters. .nr line-length-in-cm \n[line-length-in-subcm]/\n[scale-factor]u The line length is \n[line-length-in-cm]\~cm. $ groff -a EXPERIMENTS/unit-conversion2.groff <beginning of page> We're subdividing the centimeter by 1000 for arithmetic. There are 28346000 basic units per subdivided centimeter. The line length is 468000 basic units. The line length is 16510 in subdivided centimeters. The line length is 16 cm. As noted in the comment, scaled integer arithmetic can pinch on systems with 32-bit `int` type in C/C++, like amd64/x86-64. The "Numeric expressions" section of the groff(7) man page is worth review when considering the possibilities and limitations of arithmetic in the groff language. (Our Texinfo manual covers the same material.) Among other things, it notes that division truncates rather than rounding. https://man7.org/linux/man-pages/man7/groff.7.html#Numeric_expressions Regards, Branden
signature.asc
Description: PGP signature