lengthconvert.sty で単位変換の値がおかしい

lengthconvert.sty で単位変換の値がおかしい

- 浮亭 夢介 の投稿
返信数: 7
添付のように\Convertコマンドで単位変換を実行しましたが,
結果が正解値と異なってしまいました.
本パッケージはl3パッケージが必要ですが,最新版を使って
います.バージョンが異なるのか,ファイルが不足しているのか
よくわかりません.ご教示ください.

添付 foo.png
浮亭 夢介 への返信

Re: lengthconvert.sty で単位変換の値がおかしい

- 浮亭 夢介 の投稿
追加です.ソースコードは以下の通りです.

\documentclass{jarticle}
\usepackage{booktabs}
\usepackage{siunitx}
\usepackage{lengthconvert}

\begin{document}
\begin{center}
\def\arraystretch{1.4}
\begin{tabular}{lll}
\toprule
与式 & 実行結果 & 正解 \\
\midrule
\verb+\Convert{36pt}+ & \Convert{36pt} & 1.26526 cm \\
\verb+\Convert[precision=2]{36pt}+ & \Convert[precision=2]{36pt} & 1.27 cm \\
\verb+\Convert[use-siunitx]{36pt}+ & \Convert[use-siunitx]{36pt} & 1.265 26 cm \\
\verb+\Convert[unit=pt]{2cm}}+ & \Convert[unit=pt]{2cm} & 56.9055 pt \\
\verb+\Convert[unit=dd,number-only]{2cm}+ & \Convert[unit=dd,number-only]{2cm} & 53.18229 \\
\verb+\Convert[pt]{2cm}+ & \Convert[pt]{2cm} & 56.9055 pt \\
\verb+\Convert[scaled-point]{2cm} + & \Convert[scaled-point]{2cm} & 3729359 sp \\
\bottomrule
\end{tabular}
\end{center}
\end{document}
浮亭 夢介 への返信

Re: lengthconvert.sty で単位変換の値がおかしい

- 前田 一貴 の投稿
l3fp の仕様変更なのかバグなのか…….以前がどうだったのか知りませんが,
  L3 Module: l3fp 2015/08/25 v5890 L3 Floating points
では次のようになるようです.

\documentclass{minimal}
\usepackage{expl3}
\begin{document}
\noindent
\ExplSyntaxOn
\fp_eval:n {round(\dim_to_fp:n {36pt} / 1cm, 5)}\\                % 1024.29921: lengthconvert が使っている式
\fp_eval:n {round(\dim_to_fp:n {36pt} / \dim_to_fp:n {1cm}, 5)}\\ % 1.26526: これが正しい

\fp_eval:n {round(1cm, 5)}\\                                      % 28.45276
\fp_eval:n {round(36 * 1cm, 5)}\\                                % 1024.29921
\fp_eval:n {round(1 / 1cm, 5)}\\                                  % 28.45276: ??
\end{document}
前田 一貴 への返信

Re: lengthconvert.sty で単位変換の値がおかしい

- Z. R. の投稿

どうやら原因は、「l3fp における演算子の優先順位規則(仕様)が変わったから」のようです。

例えば、次のような例を試してみると、TL2013 と TL2015(最新)で結果が異なる部分があります(結果の値は小数第 5 位まで示した)。

\documentclass[a4paper]{article}
\usepackage{expl3}
\begin{document}

\ExplSyntaxOn
\typeout{%                  %  TL2015     TL2013
  \fp_eval:n{1+2mm} /       %  6.69055    6.69055
  \fp_eval:n{(1+2)mm} /     %  8.53582    8.53582
  \fp_eval:n{1+(2mm)}^^J%   %  6.69055    6.69055
  \fp_eval:n{1/2mm} /       %  0.17572    1.42263   ←相違
  \fp_eval:n{(1/2)mm} /     %  1.42263    1.42263
  \fp_eval:n{1/(2mm)}^^J%   %  0.17572    0.17572
  \fp_eval:n{1/2*mm} /      %  1.42263    1.42263
  \fp_eval:n{(1/2)*mm} /    %  1.42263    1.42263
  \fp_eval:n{1/(2*mm)}}     %  0.17572    0.17572
\ExplSyntaxOff

\end{document}

l3fp の規則では、1mm などの「長さ」は「pt 単位の数値」と同等に扱われます(1mm = 2.84527)。これは、ptmm などの「長さ単位」が pie と同類の「定数」として扱われているからです(pt = 1、mm = 2.84527)。

これを考えると、結果が異なる理由を次のように説明できます。

  • 「連接による乗算」に高い優先順位を持たせているか否かが違う。
    • TL2013 では「連接による乗算」は「除算(/)」より高い優先順位をもつ。
      1/2mm = 1/(2mm)1/2*mm
    • TL2015 では「連接による乗算」は「通常の乗算(*)」と同じ(従って「除算」とも同じ)優先順位をもつ。
      1/2mm = (1/2)mm = 1/2*mm

「連接による乗算に高い優先順位を持つか」については、最近論争になったのを覚えている人もいるでしょう(昔から論争の種であるようでうが)。

\typeout{%                  %  TL2015     TL2013
  \fp_eval:n{1/2pi}}        %  1.57079    0.15915

ひょっとしたら、そこでの知見(最近は“持たない派”が優勢?)が影響しているのかも知れません。

Z. R. への返信

Re: lengthconvert.sty で単位変換の値がおかしい

- Akira Kakuto の投稿
前田さんと,ZR さんによる解です。 Stack Exchange で似たようなものがあった
ので,l3 も知らないのに前田さんのアイデアをパクッて答えていて,識者に
訂正してもらったものです:

\documentclass{article}
\usepackage{booktabs}
\usepackage{siunitx}
\usepackage{lengthconvert}
%
\ExplSyntaxOn
\cs_new:Npn \__lconv_calc_dim_fixed:n #1
{
  \fp_eval:n
    {
      round( \dim_to_fp:n { #1 } / (1\l__lconv_unit_tl) , \l__lconv_precision_int)
    }
}
\cs_set_eq:NN \__lconv_calc_dim:n \__lconv_calc_dim_fixed:n
\ExplSyntaxOff
%
\begin{document}
\begin{center}
\def\arraystretch{1.4}
\begin{tabular}{lll}
\toprule
example & result & right value\\
\midrule
\verb+\Convert{36pt}+ & \Convert{36pt} & 1.26526 cm \\
\verb+\Convert[precision=2]{36pt}+ & \Convert[precision=2]{36pt} & 1.27 cm \\
\verb+\Convert[use-siunitx]{36pt}+ & \Convert[use-siunitx]{36pt} & 1.265 26 cm \\
\verb+\Convert[unit=pt]{2cm}+ & \Convert[unit=pt]{2cm} & 56.9055 pt \\
\verb+\Convert[unit=dd,number-only]{2cm}+ & \Convert[unit=dd,number-only]{2cm} & 53.18229 \\
\verb+\Convert[pt]{2cm}+ & \Convert[pt]{2cm} & 56.9055 pt \\
\verb+\Convert[scaled-point]{2cm} + & \Convert[scaled-point]{2cm} & 3729359 sp \\
\bottomrule
\end{tabular}
\end{center}
\end{document}
Akira Kakuto への返信

Re: lengthconvert.sty で単位変換の値がおかしい

- 前田 一貴 の投稿
http://tex.stackexchange.com/questions/270857/converting-lengths-with-lengthconvert-and-l3fp
http://chat.stackexchange.com/transcript/41?m=24244173#24244173

あたりでしょうか.ありがとうございます.
Z. R. への返信

Re: lengthconvert.sty で単位変換の値がおかしい

- 前田 一貴 の投稿
> 「連接による乗算に高い優先順位を持つか」
なるほど! 1/1cm = (1/1)cm なわけですか.
すっきりしました.ありがとうございました.

私の場合,1/2pi は 1/(2pi) と読みたくなっちゃうなあ…….
大抵のプログラミング言語だと,1/2pi という連接による乗算は認められなくて,
1/(2*pi) か 1/2/pi と書くから問題にならないのですが.