groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Groff] Integer arithmetic


From: Ted Harding
Subject: RE: [Groff] Integer arithmetic
Date: Wed, 14 Oct 2009 22:57:16 +0100 (BST)

On 14-Oct-09 11:12:19, Miklos Somogyi wrote:
> Hello, in real world this is sooo easy:
> 
> h = 105,5 mm
> w = h *0.36
> 
> In groff world 105.5 and 0.36 needs to come in centimeters, then some  
> correction needs to be applied.
> 
> Let's say that h is already done and contains roughly 300,000u.
> The 0.36 may come as some 10,000 for 0.36c and some 28,000 for 1c with 
> which we need to divide 0.36c
> 
> We have an  A * B / C thing to be executed either as (A * B) / C or  
> (A / C) * B.
> The first one may result in an overflow, the second may lose precision.
> 
> How do you handle similar problems? Divide B and C with 10? Or with  
> 100 before turning to, say, (A*B)/C?
> One can spend too much time on things like this.
> 
> Miklos

Hi, Miklos!
I agree that the integer arithmetic in groff can give rise to very
irritating limitations! The main ones, as you point out, are overflow
and truncation.

However, groff will deal correctly with conversion of fractional
spatial units into the (truncated) whole number of device units:
e.g. 0.1i will become 7200u, etc.; and you can successfully use
things like 0.275m, 2.5p, 1.75c etc.

When accurate fractional arithmetic is needed, I myself hand it
over to PIC, since this has a built-in numerical engine.
You can then pass the co9mputed values on to troff using the PIC
command "command".

So, for instance, you could try the following (the ".LP" assumes
ms macros, though this is not essential):

.nr DD 0
.LP
0.36 times 105.5 cm in \[ql]u\[qr] units
.br
.PS T
h  = 105.5
wc =h*0.36
wu = h*0.36*72000/25.4
command ".ds wstring " sprintf("%.7f",wu)
command ".nr wnumber " wc/10 "c"
.PE
wstring: \*[wstring]
.br
wnumber: \n[wnumber]


with output to the PostScript device (where 1000u = 1p = 1i/72).
I have assumed the current international definition of 1 inch,
equal to exactly 25.4mm.

The line
  command ".ds wstring " sprintf("%.7f",wu)
means that troff will see the line

.ds wstring <whatever wu evaluates to, to 7 decimal places>

i.e.

.ds wstring 107659.8425197

and similarly the line
  command ".nr wnumber " wc/10 "c"
means that troff will see the line

.nr wnumber <whatever wc/10 evaluates to>c

i.e.

.nr wnumber 3.798c

Regarding the ".PS T" -- I have somewhere (it seems to have got
lost but I'll find it) a re-definition of the .PS and .PE macros
so that ".PS T" ("T" for "tacit") means that PIC will have no
effect on the printed page (i.e. not insert any line spacing);
so long, of course, as you do not give PIC any instructions to
draw stuff. Since in the above it is only doing arithmetic, it
will not draw anything.

The result of the above is that the number register \n[wnumber]
is set to 107659 which is the truncated value of the number of
"u" in 105.5*0.36mm namely 107659.8425197 (as shown by the value
of \*[wstring]), so you have lost precision to the extent of 1
in 107659 (which you can probably live with)!

I hope this helps -- and I will later find (or re-invent) the
definition of .PS and .PE which admits the argument "T".

Ted.

--------------------------------------------------------------------
E-Mail: (Ted Harding) <address@hidden>
Fax-to-email: +44 (0)870 094 0861
Date: 14-Oct-09                                       Time: 22:57:13
------------------------------ XFMail ------------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]