Various source on the Web (e.g., http://www.prepressure.com/library/paper-size) specify the A4 paper size as 210 mm × 297 mm or 595 pt × 842 pt. Using 1 pt = 25.4 mm / 72, the width 210 mm ≈ 595.275590551 pt is closer to 595 mm than to 596 mm both in terms of absolute and relative errors.
The relative errors to the ideal ratio ⎷2 are |297/210 - ⎷2|/⎷2 ≈ 0,000051019 = 0,0051019 % and |842/595 - ⎷2|/⎷2 ≈ 0,000645226 = 0,0645226 %, respectively.
Now run latex
followed by dvips
on
\documentclass[a4paper]{article}%% either use the option a4paper or:
%\setlength\paperheight{297mm}%
%\setlength\paperwidth{210mm}
\begin{document}
Test
\end{document}
In the resulting Postscript file, we see
%%BoundingBox: 0 0 596 842
…
%%DocumentPaperSizes: a4
…
{ pop << /PageSize [595 842] >> setpagedevice }
The width of the bounding box is different from what the Web sources usually specify. Also notice that the relative error to the ideal ratio is |842/596 - ⎷2|/⎷2 ≈ 0,001033708 = 0,1033708 %, which is worse.
So why 596 and not 595? Any rationale? Is this still within the (coarse) accuracy of TeX or is there a bug there? Any chance to improve this?
Using Knuth's point, which is 1/72.27 in = 25,4 mm / 72.27 ≈ 0.351459804 mm, we'd arrive at the paper size of ≈ 597.507874016 pt × 845.046850394 pt, so I hypothesize that it's NOT Knuth's points which are meant in the Postscipt file.
PS. Looking into topoints(integer i)
pointed out by David in https://tug.org/svn/texlive/trunk/Build/source/texk/dvipsk/output.c?revision=61701&view=markup, we discover that the code there, i += 65780L; return (i / 6578176L)*100 + (i % 6578176) * 100 / 6578176;
, does not correspond to its comment. Namely, the code does NOT always perform ⌈i/65781.76⌉, as can be witnessed by i=1: the code yields (65781/6578176)·100 + (65781%6578176)·100/6578176 = 0·100 + 65781·100/6578176 = 0 + 6578100/6578176 = 0, whereas it should yield ⌈1/65781.76⌉ = 1. Overflows start with i=2147417868. If we wish (for whatever reason) to upround the results of the division, we have to mind this:
Let 𝑖∈ℕ₀, 𝑐 = 𝑔/ℎ ∈ ℚ₊, 𝑐>1, 𝑔,ℎ ∈ ℕ₊. Task: compute ⌈𝑖/𝑐⌉.
Claim: For integers 𝑑,𝑒⩾1 we have ⌈𝑑/𝑒⌉ = ⌊(𝑑+𝑒-1)/𝑒⌋.
Proof. If 𝑑|𝑒 then LHS = 𝑑/𝑒 = ⌊𝑑/𝑒+(𝑒-1)/𝑒⌋ = RHS. Otheriwse, 𝑑∤𝑒. Then LHS = ⌊𝑑/𝑒⌋+1 = ⌊(𝑑-1)/𝑒⌋+1 = ⌊(𝑑-1)/𝑒+1⌋ = RHS. QED
So ⌈𝑖/𝑐⌉ = ⌈ℎ𝑖/𝑔⌉ = ⌊(ℎ𝑖+𝑔-1)/𝑔⌋.
As 65781.76 = 1644544/25, we'd have to replace the function body with return (25LL*i+1644543)/1644544;
. This requires long long
from C99 and avoids overflow only if long long
is wider than int
. With a little more math, we can avoid overflow in C89 while using only arithmetics on int
: http://stackoverflow.com/a/78127921.
However, I see no overly convincing reason to upround. For simple rounding of i/65781.76 towards the nearest integer, we have to compute the rounding of 25i/1644544, e.g., via return (25LL*i+822272)/1644544;
, since the integer division /
in C rounds down.