% This is file texdimens.tex, part of texdimens package, which
% is distributed under the LPPL 1.3c. Copyright (c) 2021 Jean-François Burnol
% 2021/11/04 v0.99d
\edef\texdimensendinput{\endlinechar\the\endlinechar%
\catcode`\noexpand _=\the\catcode`\_%
\catcode`\noexpand @=\the\catcode`\@\relax\noexpand\endinput}%
\endlinechar13\relax%
\catcode`\_=11 \catcode`\@=11 % only for using \p@ of Plain. Check exists?
%
% Mathematics ("down" and "up" macros)
% ===========
%
% In the entire discussion here, "uu" stands for some core unit,
% or some unit corresponding to a dimension > 1pt. For the case
% of a unit corresponding to a dimension < 1pt, i.e. to
% \texdimenwithunit macro added at 0.99, refer to the
% comments of issue #2 on the tracker site.
%
% Is T sp attainable from unit "uu"?.
% If not, what is largest dimension < Tsp which is attainable?
% Here we suppose T>0.
%
% phi>1, psi=1/phi, psi<1.
%
%     U(N,phi)=trunc(N phi) is the strictly increasing sequence,
%     indexed by non-negative integers, of attainable dimensions.
%     (in sp unit)
%
%     U(N)<= T <  U(N+1)    iff    N = ceil((T+1)psi) - 1
%     U(M)<  T <= U(M+1)    iff    M = ceil(T psi)    - 1
%
% Stumbling block
% ---------------
%
% The stumbling block is that computing "ceil((T+1)psi) - 1" without
% overflow is not obvious: yes \numexpr/\dimexpr allow so-called
% "scaling operations" but only in the "rounding up" variant.
%
% If we attempt computing the ceil(x) function via round(x+0.5),
% for example with psi=100/7227 which corresponds to the unit "in",
% this necessitates evaluating:
%
%     round((((T+1)*200)+7227)/14454)
%
% But as far as I can tell currently, for this we need to be able
% to evaluate without overflow (T+1)*200+7227 and this limits to
% T's which are (roughly) such that 100 T is less than \maxdimen.
%
% A work-around
% -------------
%
% The rest of the discussion is about an algorithm providing an
% alternative route to N, using \numexpr/\dimexpr/TeX facilities,
% and working with (almost, as we will see) the full range of allowed
% T's, 0 < T <= \maxdimen. (that the algorithm works for T=0 is to be
% checked manually after the main discussion).
%
% Let's return to the U(N)<= T < U(N+1) and U(M)< T <= U(M+1) equations.
%
% Either (recall in all of this T > 0):
%
% case1:  M = N, i.e. T is not attainable, M=N < T psi < (T+1) psi <= N+1
% case2:  M = N - 1, i.e. T is attained, T psi <= N < (T+1) psi, T = trunc(N phi)
%
% Let X = round(T psi). And let Y = trunc(X phi). We will explain later
% how X and Y can be computed using \numexpr/\dimexpr/TeX.
%
% case1: X can be N or N+1. It will be N+1 iff Y > T.
% case2: X can be N or N-1. It will be N iff trunc((X+1)phi)>T.
%
% This is not convenient: if Y < T it could be that we are in case 2
% but to decide we must check if trunc((X+1) phi) = T or not, so
% this means a second computation.
%
% If psi < 0.5
% ------------
%
% The situation then simplifies:
%
% case1: X can be N or N+1. It will be N+1 iff Y = trunc(X phi) > T.
% case2: X is necessarily N.
%
% Thus:
% a) compute X = round(T psi)
% b) compute Y = trunc(X phi) and test if Y > T. If true, we
%    were in case 1, replace X by X - 1, else we were either
%    in case 1 or case 2, and we leave X as it is.
% We have thus found N.
%
% The operation Y = trunc(X phi) can be achieved this way:
% i) use \the\dimexpr to convert X sp into D pt,
% ii) use \the\numexpr\dimexpr  to convert "D uu" into sp.
% These steps give Y.
%
% This way we find the maximal dimension at most T sp exactly
% representable in "uu" unit.
%
% The computations of X and Y can be done independently of sign of T.
% But the final test has to be changed to Y < T if T < 0 and then
% one must replace X by X+1. So we must filter out the sign of the input.
%
% If the goal is only to find a decimal D such that "D uu" is
% exactly T sp in the case this is possible, then things are simpler
% because from X = round(T psi) we get D such as X sp is same as D pt
% and "D uu" will work.
% We don't have to take sign into account for this computation.
% But if T sp was not attainable we don't know if this X will give
% a D such that D uu < T sp or D uu > T sp.
%
% If psi > 0.5
% ------------
%
% For example unit "bp" has phi=803/800.
%
% It is then not true that if T sp is attainable, the X = round(T psi)
% will always work.
%
% But it is true that R = round((T + 0.5) psi) will always work.
% Here we must use -0.5 if T < 0, though.
%
% This R=round((T+0.5) psi) can always be computed via \numexpr because 2T+1
% will not trigger arithmetic overflow.
%
% So this gives an approach to find a D such that "D uu" is exactly
% T sp when this is possible.
%
% If Tsp (positive) is not attainable, this R however can produce
% either N or N+1.
%
% But we can decide what happened by computing Z = trunc(R phi).
% If and only if Z > T this means R was N+1.
%
% It is slightly less costly to compute X = round(T psi) than
% R = round((T + 0.5) psi),
% but if we then realize that trunc(X phi) < T  we do not yet know
% if trunc((X+1) phi) = T  or is > T. So we proceed via R, not X,
% to not have to make a second computation if a dimension comparison
% test goes awry.
%
% To recapitulate: we have our algorithm for all units to find out
% maximal dimension exactly attainable in "uu" unit and at most equal
% to (positive) T sp.
%
% Unfortunately the check that Y (in case psi < 0.5) or Z (in case psi >
% 0.5) verifies or not Y > T may trigger a Dimension too large error if
% T sp was near non-attainable \maxdimen. It turns out this sad
% situation happens only for the units `dd`, `nc`, and `in`, and T sp
% very close to \maxdimen (like for all units apart from `pt`, `bp`,
% `nd`, the \maxdimen is not attainable, and by bad luck for `dd`, `nc`,
% and `in`, the X will correspond to a decimal D such that Duu>\maxdimen
% is the nearest virtually attaible dimensions from above not from
% below; see the README.md for the tabulation of the maximal usable inputs).
%
% Regarding the \texdimen<uu> macros, and units with phi > 2, I
% hesitated using either the round((T+0.5)psi) or round(T psi), but for
% Tsp = \maxdimen, both formulas turned out to give the same result for
% all such units, so I chose for these \texdimen<uu> macros and the
% units with phi>2 to use the simpler round(T psi) which does not need
% to check the sign of T.
%
% For the "up" and "down" macros, we again use the round(T psi), but do
% have to check the sign anyhow. We could also have used the
% round((T+0.5)psi) which requires a sign check too, but it costs a bit
% more. It would have allowed though to share the same codebase for all
% units, here we have to prepare some slightly different shared macros
% for the first batch bp, nd, dd and the second batch mm, pc, nc, cc,
% cm, in.
%
% Implementation
% ==============
%
\def\texdimenfirstofone#1{#1}%
{\catcode`p 12\catcode`t 12
 \csname expandafter\endcsname\gdef\csname texdimenstrippt\endcsname#1pt{#1}}%
%
% down macros:
% for units with phi < 2:
\def\texdimendown_A#1{\if-#1\texdimendown_neg\fi\texdimendown_B#1}%
\def\texdimendown_B#1;#2;{\expandafter\texdimendown_c\the\numexpr(2*#1+1)#2;#1;}%
% for units with phi > 2:
\def\texdimendown_a#1{\if-#1\texdimendown_neg\fi\texdimendown_b#1}%
\def\texdimendown_b#1;#2;{\expandafter\texdimendown_c\the\numexpr#1#2;#1;}%
% shared macros:
\def\texdimendown_c#1;{\expandafter\texdimendown_d\the\dimexpr#1sp;#1;}%
{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimendown_d#1PT};#2;#3;#4;%
   {\ifdim#1#4>#3sp \texdimendown_e{#2}\fi\texdimenfirstofone{#1}}%
}%
% this #2 will be \fi
\def\texdimendown_e#1#2#3#4{#2\expandafter\texdimenstrippt\the\dimexpr\numexpr#1-1sp\relax}%
% negative branch:
% The problem here is that if input very small, output can be 0.0, and we
% do not want -0.0 as output.
% So let's do this somewhat brutally and non-efficiently.
% Anyhow, negative inputs are not our priority.
% #1 is \fi here and #2 is \texdimendown_b or _B:
\def\texdimendown_neg#1#2-#3;#4;#5;{#1\expandafter\texdimenstrippt\the\dimexpr-#2#3;#4;#5;pt\relax}%
%
% up macros:
\def\texdimenup_A#1{\if-#1\texdimenup_neg\fi\texdimenup_B#1}%
\def\texdimenup_B#1;#2;{\expandafter\texdimenup_c\the\numexpr(2*#1+1)#2;#1;}%
\def\texdimenup_a#1{\if-#1\texdimenup_neg\fi\texdimenup_b#1}%
\def\texdimenup_b#1;#2;{\expandafter\texdimenup_c\the\numexpr#1#2;#1;}%
\def\texdimenup_c#1;{\expandafter\texdimenup_d\the\dimexpr#1sp;#1;}%
{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimenup_d#1PT};#2;#3;#4;%
   {\ifdim#1#4<#3sp \texdimenup_e{#2}\fi\texdimenfirstofone{#1}}%
}%
% this #2 will be \fi
\def\texdimenup_e#1#2#3#4{#2\expandafter\texdimenstrippt\the\dimexpr\numexpr#1+1sp\relax}%
% negative branch:
% Here we can me more expeditive than for the "down" macros.
% But this breaks f-expandability.
% #1 will be \fi and #2 is \texdimenup_b or _B:
\def\texdimenup_neg#1#2-{#1-#2}%
%
% pt
%
\def\texdimenpt#1{\expandafter\texdimenstrippt\the\dimexpr#1\relax}%
%
% bp 7227/7200 = 803/800
%
\def\texdimenbp#1{\expandafter\texdimenbp_\the\numexpr\dimexpr#1;}%
\def\texdimenbp_#1#2;{%
    \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*400/803sp\relax
}%
% \texdimenbpdown: maximal dim exactly expressible in bp and at most equal to input
\def\texdimenbpdown#1{\expandafter\texdimendown_A\the\numexpr\dimexpr#1;*400/803;bp;}%
% \texdimenbpup: minimal dim exactly expressible in bp and at least equal to input
\def\texdimenbpup#1{\expandafter\texdimenup_A\the\numexpr\dimexpr#1;*400/803;bp;}%
%
% nd 685/642
%
\def\texdimennd#1{\expandafter\texdimennd_\the\numexpr\dimexpr#1;}%
\def\texdimennd_#1#2;{%
    \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*321/685sp\relax
}%
% \texdimennddown: maximal dim exactly expressible in nd and at most equal to input
\def\texdimennddown#1{\expandafter\texdimendown_A\the\numexpr\dimexpr#1;*321/685;nd;}%
% \texdimenndup: minimal dim exactly expressible in nd and at least equal to input
\def\texdimenndup#1{\expandafter\texdimenup_A\the\numexpr\dimexpr#1;*321/685;nd;}%
%
% dd 1238/1157
%
\def\texdimendd#1{\expandafter\texdimendd_\the\numexpr\dimexpr#1;}%
\def\texdimendd_#1#2;{%
    \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*1157/2476sp\relax
}%
% \texdimendddown: maximal dim exactly expressible in dd and at most equal to input
\def\texdimendddown#1{\expandafter\texdimendown_A\the\numexpr\dimexpr#1;*1157/2476;dd;}%
% \texdimenddup: minimal dim exactly expressible in dd and at least equal to input
\def\texdimenddup#1{\expandafter\texdimenup_A\the\numexpr\dimexpr#1;*1157/2476;dd;}%
%
% mm 7227/2540 phi now >2, use from here on the simpler approach
%
\def\texdimenmm#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*2540/7227\relax}%
% \texdimenmmdown: maximal dim exactly expressible in mm and at most equal to input
\def\texdimenmmdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*2540/7227;mm;}%
% \texdimenmmup: minimal dim exactly expressible in mm and at least equal to input
\def\texdimenmmup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*2540/7227;mm;}%
%
% pc 12/1
%
\def\texdimenpc#1{\expandafter\texdimenstrippt\the\dimexpr(#1)/12\relax}%
% \texdimenpcdown: maximal dim exactly expressible in pc and at most equal to input
\def\texdimenpcdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;/12;pc;}%
% \texdimenpcup: minimal dim exactly expressible in pc and at least equal to input
\def\texdimenpcup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;/12;pc;}%
%
% nc 1370/107
%
\def\texdimennc#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*107/1370\relax}%
% \texdimenncdown: maximal dim exactly expressible in nc and at most equal to input
\def\texdimenncdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*107/1370;nc;}%
% \texdimenncup: minimal dim exactly expressible in nc and at least equal to input
\def\texdimenncup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*107/1370;nc;}%
%
% cc 14856/1157
%
\def\texdimencc#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*1157/14856\relax}%
% \texdimenccdown: maximal dim exactly expressible in cc and at most equal to input
\def\texdimenccdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*1157/14856;cc;}%
% \texdimenccup: minimal dim exactly expressible in cc and at least equal to input
\def\texdimenccup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*1157/14856;cc;}%
%
% cm 7227/254
%
\def\texdimencm#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*254/7227\relax}%
% \texdimencmdown: maximal dim exactly expressible in cm and at most equal to input
\def\texdimencmdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*254/7227;cm;}%
% \texdimencmup: minimal dim exactly expressible in cm and at least equal to input
\def\texdimencmup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*254/7227;cm;}%
%
% in 7227/100
%
\def\texdimenin#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*100/7227\relax}%
% \texdimenindown: maximal dim exactly expressible in in and at most equal to input
\def\texdimenindown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*100/7227;in;}%
% \texdimeninup: minimal dim exactly expressible in in and at least equal to input
\def\texdimeninup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*100/7227;in;}%
% both in and cm
% Mathematics ("both" macros)
% ===========
%
% Let a and b be two non-negative integers such that U = floor(a 7227/100) = 
% floor(b 7227/254).  It can be proven that a=50k, b=127k for some integer k.
% The proof is left to reader.  So U = floor(7227 k /2) for some k.
%
% Let's now find the largest such U <= T. So U = floor(k 7227/2)<= T which is
% equivalent (as k is integer) to k 7227/2 <= T + 1/2, i.e.
%
%     kmax = floor((2T+1)/7227)
%
% If we used for x>0 the formula floor(x)=round(x-1/2)=<x-1/2> we would end
% up basically with some 4T hence overflow problems even in \numexpr.
% Here I used <.> to denote rounding in the sense of \numexpr. It is not
% 1-periodical due to how negative inputs are handled, but here x-1/2>-1/2.
%
% The following lemma holds: let T be a non-negative integer then
%
%     floor((2T+1)/7227) = <(2T - 3612)/7227>
%
% So we can compute this k, hence get a=50k, b=127k, all within \numexpr and
% avoiding overflow.
%
% Implementation
% ==============
%
% Regarding the output in pt or sp, we seem to need floor(k 7227/2).
% The computation of floor(k 7227/2) as <(7227 k - 1)/2> would require to
% check if k==0 so we do it rather as <(7227 k + 1)/2> - 1.  No overflow
% can arise as k = 297147 for \maxdimen, and then 7227 k = 2**31 - 2279 and
% there is ample room for 7227k+1 using \numexpr.
%
% But this step, as well as initial step to get kmax will require to separate
% handling of negative input from positive one.
%
% Alternative
% -----------
%
% For non-negative T we can compute U = ((T+1)/7227)*7227. If U <= T keep it,
% else if U > T, replace it by U - 3614. This is alternative road to the maximal
% floor(k 7227/2) at most equal to T.
%
% There is some slight under-efficiency to share macros across the 3 end targets
% as I added one layer of parentheses.
\def\texdimenbothincm#1{\expandafter\texdimenstrippt\the\dimexpr
                        \expandafter\texdimenboth_a\the\numexpr\dimexpr#1;127);}%
\def\texdimenbothcmin#1{\expandafter\texdimenstrippt\the\dimexpr
                        \expandafter\texdimenboth_a\the\numexpr\dimexpr#1;50);}%
\def\texdimenbothincmpt#1{\expandafter\texdimenstrippt\the\dimexpr
                          \expandafter\texdimenboth_a\the\numexpr\dimexpr#1;7227+1)/2-1;}%
\let\texdimenbothcminpt\texdimenbothincmpt
\def\texdimenboth_a#1{\if-#1\texdimenboth_neg\fi\texdimenboth_b#1}%
% The opening parenthesis ( is closed in #2, it was added to share "pt" output
% with the two others
\def\texdimenboth_b#1;#2;{\numexpr(((2*#1-3612)/7227)*#2sp\relax}%
% negative branch. This is expanded in a \dimexpr so we can insert the -
% in front of the \numexpr.
% #1 is \fi here and #2 is \texdimenboth_b
\def\texdimenboth_neg#1#2-#3;#4;{#1-\numexpr(((2*#3-3612)/7227)*#4sp\relax}%
%
% \texdimenbothincmsp is done separately as I found no easy way to share
% its macros with the others; alternative would have been to make it the
% core, and derive the others from it, (\texdimencm{\texdimenbothincmsp{...}sp})
% but then they would be less efficient than their current versions.
% (it is a bit ironical to worry about not creating too many macros
% in such a small package, by the way)
\def\texdimenbothincmsp#1{\the\numexpr\expandafter\texdimenbothsp_a\the\numexpr\dimexpr#1;}%
\def\texdimenbothsp_a#1{\if-#1\texdimenbothsp_neg\fi\texdimenbothsp_b#1}%
\def\texdimenbothsp_b#1;{(((2*#1-3612)/7227)*7227+1)/2-1\relax}%
% #1 is \fi
% we need to regrab here or to add a \numexpr..\relax layer to
% \texdimenbothsp_b (parentheses could do but using 0-(...) syntax)
% finally doing the job of \texdimenbothsp_b directly
\def\texdimenbothsp_neg#1#2-#3;{#1-\numexpr(((2*#3-3612)/7227)*7227+1)/2-1\relax\relax}%
%
\let\texdimenbothcminsp\texdimenbothincmsp
% (\texdimenwithunit, added at 0.99)
% Mathematics
% ===========
%
% As explained in the README.md, the ex and em units are
% handled by TeX as if multiplying by a conversion factor f/65536
% (here f sp = 1ex resp. = 1em).
% In particular, for any decimal D, input "D em" is handled the exact
% same way as input "D\dimexpr 1em\relax"; this is not
% the case for the core units except for pt and pc (and sp), whose
% conversion factors are the sole ones with a power of 2 denominator
% (respectively 1, 1, and 65536).  The further difference is that
% for the core units apart from sp, the conversion factor is >1.
%
% We assume for this discussion T is non-negative.
% If f/65536 > 1, the analysis is as above : some dimensions T sp
% are not attainable as D uu, but the formula
%     N=round((2T+1)*32768/f)
% will give a suitable decimal D via \the\dimexpr N sp\relax.
% (if T=0, we get N=0 as 32768/f<0.5)
% This D will let TeX convert D uu into T sp, if the dimension
% is attainable else it will be a closest match
% either from above or below (not necessarily nearest overall).
%
% If f/65536=1, attention that above formula would give N=1 for
% T=0 (was bug #4).
%
% If f/65536<1, all dimensions Tsp are attainable as D uu. Indeed
% D uu is parsed by TeX via N=round(D*65536), then T=trunc(N*phi),
% with phi=f/65536. Starting from T we need to find an N such that
% T/phi <= N< (T+1)/phi. We first consider v=(T+0.5)/phi. As its
% distance to the extremities is 0.5/phi>0.5,(*) its rounding M
% to an integer verifies automatically T/phi < M < (T+1)/phi, so
% is a candidate. The TeX core conversion of Msp to a Dpt with
% D a decimal of at most 5 fractional digits will provide a D
% such that indeed M=round(D*65536).
%
% (*) attention that this fails if phi=1, we definitely can not
% use the N=round((2T+1)*32768/f) formula for f=65536, it gives
% N=T+1 in place of N=T... It is funny the formula works for all
% f apart from f=65536...
%
% Attention that if T=0, the M=round(0.5/phi) will be at least 1,
% so the produced decimal D will not be 0.0, although it will
% be true that D \dimexpr f sp\relax produces the zero dimension,
% the above analysis being correct even for T=0.
%
% Implementation
% ==============
%
% \texdimenwithunit{dim1}{dim2}. dim2>0 assumed.
% We first get f from dim2 and branch according to whether f>65536,
% f=65536 or f<65536.
% We will also need to check the sign of T (dim1=T sp).
% We then compute in both branches round((2T+1)*32768/f), but
% in an indirect way in the f<65536 branch to avoid overflow.
% We will need also to intercept T=0 to avoid producing a non
% pleasing positive D in that case (still correct for f<65536;
% this is issue #3).
%
% In the f<65536 branch we first do the Euclidean division
% 2T+1 = k*2*f + R with 0<=R<2f. The k is obtained as round((2T+1-f)/(2f))
% which can be computed in a numexpr (and never gives -1 even for T=0)
% Then (2T+1)*32768/f=65536*k + R*32768/f
% Then R*32768/f<=65536-32768/f<65536-32768/65536=65536-0.5
% Hence the numexpr evaluation gives an integer B<65536.
%
% N.B.: if f>=65536, we still have R*32768/f<65536 as R<2f
% so the only difference is that the B could be here 65536
%
% From \the\dimexpr Bsp, we get a decimal E < 1, so E=0.ddddd
% (or less digits) and the looked for D will be the contatenation
% k.ddddd with k as obtained earlier. This procedure has no possible
% arithmetic overflow.
%
% #2 is assumed positive. The case #2=1pt=65536sp is special, and
% must be filtered out (issues #4, #6).
% pre-multiplication of #1 by 2 here
\def\texdimenwithunit#1#2{\expandafter\texdimenwithunit_
    \the\numexpr\dimexpr#2\expandafter;\the\numexpr2*\dimexpr#1;}%
\let\texdimenorthat\texdimenfirstofone
\def\texdimendothis#1#2\texdimenorthat#3{\fi#1}%
\def\texdimenwithunit_#1;#2{%
        \ifnum#1=\p@\texdimendothis\texdimenwithunit_p@\fi
        \ifnum#1>\p@\texdimendothis\texdimenwithunit_A\fi
        \texdimenorthat\texdimenwithunit_B#2#1;%
}%
% we premultiplied the first argument by 2... must be undone now!
% and we must avoid overflow. Very underoptimal, but user is not
% supposed to do something as silly as actually using this unit=1pt case!
\def\texdimenwithunit_p@#1#2;#3;{\expandafter\texdimenstrippt\the\dimexpr\numexpr#1#3/2sp\relax}%
% unit>1pt, handle this as for bp. Attention it would be wrong for unit=1pt!
\def\texdimenwithunit_A#1#2;#3;{\expandafter\texdimenstrippt
    \the\dimexpr\numexpr(#1#3+\if-#1-\fi1)*32768/#2sp\relax
}%
% unit<1pt. Attention it would be wrong for unit=1pt!
% if dim1<0, simply negate result for dim1>0 as it can not possibly be 0.0
% Indeed (2T+1)*32768/f will be at least 3*32768/f so its rounding at least 2.
% Add a check for dim1=0 to fix issue #3
\def\texdimenzerominusfork #10-#2#3\krof {#2}%
\def\texdimenwithunit_B#1{\texdimenzerominusfork
                           #1-\texdimenwithunit_Bzero
                           0#1\texdimenwithunit_Bneg
                           0-\texdimenwithunit_Ba
                          \krof#1}%
\def\texdimenwithunit_Ba#1#2;#3;{\expandafter\texdimenwithunit_Bb\the\numexpr#1#3+1;#2;}%
\def\texdimenwithunit_Bb#1;#2;{\expandafter\texdimenwithunit_Bc\the\numexpr(#1-#2)/(2*#2);#1;#2;}%
% I was hesitating between leaving k in the stream (breaking f-expandability)
% and then remove the "0" and trailing "pt" from 0.ddddd pt, but opted
% finally for doing \the\numexpr..+0.ddddd which is f-expandable and allows
% recycling strippt here with no need of another utility.
%
% This means (see the nota bene above) that we could apply this procedure
% also for f>65536, because at worst we will get a \the\numexprk+1.0, which
% gives the correct result. I tested and found about 39% longer execution time
% if dim2>1pt does same calculations as for dim2<1pt, and at the same time
% dim2<1pt was improved about 11% from skipping the conditional
\def\texdimenwithunit_Bc#1;#2;#3;{\the\numexpr#1+\expandafter\texdimenstrippt
                                  \the\dimexpr\numexpr(#2-#1*2*#3)*32768/#3sp\relax}%
% Here, definitely not caring about f-expandability. Or efficiency.
\def\texdimenwithunit_Bneg-{-\texdimenwithunit_Ba{}}%
\def\texdimenwithunit_Bzero#1;#2;{0.0}%
\texdimensendinput
