\newbox\mybox{}
\setbox\mybox=\vtop{This is the content of the box}
\the\ht\mybox\ This is the height of the box
\par
\the\mybox\ This is the number of the box\par
\box16
How do I get a rounded 6.94pt from 6.94444pt ?
\bye
2
5 个回答
5
辅助宏…
\newbox\mybox{}
\setbox\mybox=\vtop{This is the content of the box}
\the\ht\mybox\ This is the height of the box
\par
\the\mybox\ This is the number of the box\par
\box16
How do I get a rounded 6.94pt from 6.94444pt?
\newcount\mycount
\def\myrndaux#1.#2#3#4#5\nil{%
\ifnum #4>4
\mycount=#3
\ifnum\mycount<9
\advance\mycount by 1
#1.#2\the\mycount pt%
\else
\mycount=#2
\ifnum\mycount<9
\advance\mycount by 1
#1.\the\mycount 0pt%
\else
\mycount=#1
\advance\mycount by 1
\the\mycount .00pt%
\fi
\fi
\else
#1.#2#3pt%
\fi
}%
\def\mydept#1pt{#1}%
\def\myinteger#1.#2\nil{#1}%
\def\mydecimal#1.#2\nil{#2}%
\def\myrnd#1{%
\edef\tmpa{\expandafter\mydept#1}%
\edef\tmpb{\expandafter\myinteger\tmpa.0\nil
.\expandafter\mydecimal\tmpa.0\nil}%
\expandafter\myrndaux\tmpb 000\nil
}%
\myrnd{6.94444pt} (rounds up)
\myrnd{6.4999pt} (rounds down)
\myrnd{6pt} (stet)
\bye
3
-
谢谢,这样就好了。也许我对此理解得不够充分,但似乎不够准确。(6pt vs 6.94pt)。请查看我的“解决方法”答案。
–
-
@MBE 哦,我只是没有仔细阅读问题并将其四舍五入到最接近的点。如果您在排版中重复使用它,那么太精确也没有多大意义,因为尺寸算术在 tex 中本质上是不准确的。(对于大多数目的来说它“足够好”,但每一步都会引入不准确。)
– -
@MBE 无疑是一种更好的方法,但你只需要几个步骤。请参阅编辑。
–
|
以下定义了一个名为 的不可扩展纯 TeX 宏\round
。它具有语法\round{<places>}{<number-like>}
并将四舍五入<number-like>
到<places>
小数位。负数<places>
参数将四舍五入到整数部分(因此\round{-1}{5.5}
将导致10
)。
它将标记寄存器设置\roundResult
为舍入操作的结果。尾随单位保持不变。您<number-like>
应该将其扩展为具有前导整数部分的任何内容,然后如果后面是一个点,则必须有一个小数部分(因此\round{2}{3.}
会导致低级 TeX 错误)。
\begingroup
\catcode`\@=11
\def\round#1{#1}
\round{%
\endgroup
\csname newcount\endcsname\round@int
\csname newcount\endcsname\round@dec
\csname newcount\endcsname\round@places
\csname newtoks\endcsname\round@trail
\csname newtoks\endcsname\roundResult
\def\round#1#2{%
\round@places=#1\relax
\afterassignment\round@afterint
\round@int=#2\relax
}
\def\round@first#1#2\relax{#1}
\def\round@afterfi#1\fi{\fi#1}
\def\round@collect#1\relax{\roundResult={#1}}
\def\round@afterint#1{%
\ifx.#1%
\afterassignment\round@afterdec
\round@dec=%
\else
\ifnum\round@places>0
\round@places=0
\fi
\round@afterfi{\round@intloop#1}%
\fi
}
\def\round@afterdec{%
\ifnum\round@places>0
\expandafter\round@loop
\else
\ifnum\round@places=0
\ifnum\expandafter\round@first\the\round@dec\relax>4
\advance\round@int1
\fi
\fi
\expandafter\round@intloop
\fi
}
\def\round@intloop{%
\round@trail{}%
\loop\ifnum\round@places<0
\round@trail\expandafter{\the\round@trail0}%
\ifnum\round@places=-1
\advance\round@int5
\fi
\divide\round@int10
\advance\round@places1
\ifnum\round@int=0
\round@trail{}%
\round@places=0
\fi
\repeat
\expandafter\round@collect\the\expandafter\round@int\the\round@trail
}
\def\round@loop{%
\expandafter\round@count\the\round@dec\relax
\loop\ifnum\round@places<0
\ifnum\round@places=-1
\advance\round@dec5
\fi
\divide\round@dec10
\advance\round@places1
\repeat
\expandafter\round@collect
\the\expandafter\round@int\expandafter.\the\round@dec
}
\def\round@count#1{%
\ifx\relax#1%
\else
\advance\round@places-1
\expandafter\round@count
\fi
}
}
\newbox\mybox
\setbox\mybox=\vtop{This is the content of the box}
\the\ht\mybox\ This is the height of the box
\par
\round{2}{\the\ht\mybox}\the\roundResult\ This is the rounded height of the box
\par
\the\mybox\ This is the number of the box\par
\box16
How do I get a rounded 6.94pt from 6.94444pt ?
\bye
|
也许,你想要这个:
\newdimen\value
\value=6.94444pt
\the\value % prints 6.94444pt
\let\ea=\expandafter
\ea\def \ea\readvalue \ea#\ea1\detokenize{pt}{#1}
\def\modifyvalue #1.#2#3#4\end{#1.#2#3}
\value=\ea\modifyvalue\expanded{\ea\readvalue\the\value}{}{}\end pt
\the\value % prints 6.94pt
\bye
此代码会进行截断。如果您需要四舍五入,请\advance\value by 0.005pt
在截断之前进行。
2
-
3这难道不是截断而不是舍入吗?尽管给出了 OP 的自我回答,但我不再确定我是否知道问题是什么。
– -
是的,这是截断。而且只是非常脆弱的截断,因为如果我们将某个十进制表示设置为 pt 中的 dimen 值,那么它会被重新解释为 sp 的倍数,并
\the\value
可能打印出与设置不同的内容。这就是“可能”OP 想要这个的原因。我不确定。
–
|
这使用 e-TeX 扩展,以便宏可扩展。
它假设一个正维度,并利用在整数部分后\the\dimexpr
总是会添加一个小数部分(可能只是)。.0
将显示尾随零,并且可扩展性允许使用宏进行分配。由于 TeX 永远不会显示超过五个,因此没有必要超出。
%%%% requires pdftex or xetex or luatex (not Knuth TeX)
\catcode`@=11
\def\therounded#1#2{% #1 = digits, #2 = dimen
\expanded{\noexpand\therounded@{#1}\the\dimexpr#2\relax}%
}
\expanded{\def\noexpand\therounded@#1#2\detokenize{pt}}{%
\ifcase#1
\expandafter\therounded@zero\or
\expandafter\therounded@one\or
\expandafter\therounded@two\or
\expandafter\therounded@three\or
\expandafter\therounded@four\else
\expandafter\therounded@five\fi
#200000\relax pt
}
\def\therounded@zero #1.#2#3#4#5#6#7\relax{\therounded@@{}{#1}{#2}}
\def\therounded@one #1.#2#3#4#5#6#7\relax{\therounded@@{#1.}{#2}{#3}}
\def\therounded@two #1.#2#3#4#5#6#7\relax{\therounded@@{#1.#2}{#3}{#4}}
\def\therounded@three #1.#2#3#4#5#6#7\relax{\therounded@@{#1.#2#3}{#4}{#5}}
\def\therounded@four #1.#2#3#4#5#6#7\relax{\therounded@@{#1.#2#3#4}{#5}{#6}}
\def\therounded@five #1.#2#3#4#5#6#7\relax{#1.#2#3#4#5#6}
\def\therounded@@#1#2#3{#1\the\numexpr#2\ifnum#3>4 +1\fi\relax}
\catcode`@=12
\newlinechar=`^^J
\dimen0=16.90053pt
\message{%
\the\dimen0^^J%
0: \therounded{0}{\dimen0}^^J%
1: \therounded{1}{\dimen0}^^J%
2: \therounded{2}{\dimen0}^^J%
3: \therounded{3}{\dimen0}^^J%
4: \therounded{4}{\dimen0}^^J%
5: \therounded{5}{\dimen0}^^J%
}
\dimen0=16.94453pt
\message{%
\the\dimen0^^J%
0: \therounded{0}{\dimen0}^^J%
1: \therounded{1}{\dimen0}^^J%
2: \therounded{2}{\dimen0}^^J%
3: \therounded{3}{\dimen0}^^J%
4: \therounded{4}{\dimen0}^^J%
5: \therounded{5}{\dimen0}^^J%
}
\dimen2=\therounded{0}{\dimen0}
\message{\the\dimen0 \space --> \the\dimen2^^J}
\setbox0=\vtop{abc\par def\par ghi}
\message{Height plus depth: \therounded{2}{\ht0+\dp0}^^J}
\bye
控制台上的输出:
16.90053pt
0: 17pt
1: 16.9pt
2: 16.90pt
3: 16.901pt
4: 16.9005pt
5: 16.90053pt
16.94453pt
0: 17pt
1: 16.9pt
2: 16.94pt
3: 16.945pt
4: 16.9445pt
5: 16.94453pt
16.94453pt --> 17.0pt
Height plus depth: 32.89pt
|
未完待续…
\newbox\mybox{}
\setbox\mybox=\vtop{``This is the content of the box''}
\the\ht\mybox\ This is the current height of the box
\par
\newdimen\start
\start=\ht\mybox
\the\start\ This is the start of the loop\par
\newdimen\stop
\stop=6.94000pt %
\the\stop \ This is the wanted height of the box and stop of the loop
\loop \ifdim\start>\stop \advance\start by -0.00001pt\repeat\par
\the\start\ This is the resulting value
\bye
6
-
3我完全不明白这一点。为什么要用这种迂回的方式告诉 tex 使用
6.94pt
?我以为你想排版结果,而不知道结果是什么。但显然不是?
– -
2这不是我的意思。我的意思是,一旦处理 tex 维度,就无法
1pt
准确。即使存储维度也会带来不准确性。例如,如果您存储在维度寄存器中,则不一定存储1pt
在维度寄存器中。您可能有0.999pt
或1.0001pt
或其他东西。如果您想保持准确性,请存储整数并仅在最后一刻进行除法。
– -
1例如尝试
\newdimen\mydimen \mydimen=0.001pt \advance\mydimen by 0.1pt \the\mydimen
了解我的意思。
– -
1@MBE 我不明白你的代码风格。为什么在第 5 行有
\par
?前一行是空的,所以它生成了隐式的\par
,为什么后面还有显式的\par
?为什么第 5-14 行要缩进?你为什么要做这样一个荒谬的循环,其中 dimen 值减少 0.00001pt,四舍五入为 1sp?试试这个,看看这个荒谬的代码\newdimen\value \value=0.00001pt \the\value
。它打印 0.00002pt。你为什么要做这个循环,而它必须在什么时候结束\start=\stop
?你为什么不简单地写出\start=\stop
具有完全相同效果的循环?
–
-
1@MBE 我觉得你的思维方式有点奇怪。也许你想要一些东西,但在这里却呈现出不同的东西。当然,这种思维方式无法使 TeX 发挥最佳作用。对于 tex.stackexchange 也是如此。
–
|
–
sp
并进行整数运算,并在最后一刻转换为浮点数。–
♦
|