Index | Thread | Search

From:
Steffen Nurpmeso <steffen@sdaoden.eu>
Subject:
Re: exact floating point calculations in roff(7)
To:
j@bitminer.ca
Cc:
Tech <tech@openbsd.org>, schwarze@usta.de
Date:
Wed, 02 Apr 2025 23:10:03 +0200

Download raw body.

Thread
j@bitminer.ca wrote in
 <d3157b643fa5098ae72e6b7b327e0664@bitminer.ca>:
 |Hello, I think you left out the best part:
 |
 |         switch (unit) {
 |         case 'f':
 |                 myres *= 65536.0;
 |                 break;
 |     ...
 |     <snip>
 |     ...
 |         case 'M':
 |                 myres *= 24.0 / 100.0;
 |                 break;
 |         default:
 |                 break;
 |}
 |         if (res != NULL)
 |                 *res = myres;    <--- ***here***
 |
 |The whole point seems to be to calculate an integer,
 |returned in *res.
 |
 |Some programmer who might have been less inclined to write scaled
 |integer arithmetic code decided, instead, to adopt doubles.
 |
 |OK, fine, but I think an implied goal here is to generate an exact
 |*rounded* result.  Which is necessary because as often seen doubles
 |don't calculate integer values very reliably.
 |
 |While your fix is obviously valid I think the fix could also have
 |been
 |
 |
 |     *res = trunc(myres + 0.5);
 |
 |which eliminates the 23.999999 problem in the usual floating-point
 |way.

Remark: i only loosely track mandoc, i stick at version 1.14.6,
and roff_getnum() is all-integer there.
The question is why it was changed to floating-point at all.
I am a prowd stupid anti-mathematician who never used/s
floating-point, except for misusing the i386 floating point stack
as a memory copy etc speedup (that is: MMX registers), as stolen
from FreeBSD.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)