Open FloMiLe opened 12 months ago
Looks like some rounding error triggered by special (corner) values. 56.9055pt, what TeX thinks equivalent to 20mm, reproduces the problem too.
Setting \hfuzz=0pt
shows (in log) that the constructed table is just 0.00002pt wider than \linewidth
Overfull \hbox (0.00002pt too wide) in paragraph at lines
The .00002pt rounding error comes from dimension calculations. For example \the\dimexpr100pt-.4pt-.4pt-.4pt
gives 98.80002pt, 0.00002pt larger than the expected result.
l3kernel
/expl3
's l3fp
package implements a floating-point arithmetic following IEEE 754, which is more accurate/has more significant figures (up to 16).
In example below, dimension arithmetics (stored in \l__column_target_dim
) in \__tblr_collect_extendable_column_width:
are replaced with corresponding floating-point ones (stored in \l__column_target_fp
), but still kept to show difference of rounding error(s) in error message.
\__tblr_adjust_extendable_column_width_once:
and \__tblr_adjust_extendable_column_width_negative:
may require similar adjustments.
```tex \documentclass{article} \usepackage{tabularray} \hfuzz=0pt \makeatletter \ExplSyntaxOn \fp_new:N \l__column_target_fp \cs_gset_protected:Npn \__tblr_collect_extendable_column_width: { \tl_set:Nx \l_tmpa_tl { \__tblr_prop_item:nn { inner } { width } } \tl_if_empty:NTF \l_tmpa_tl { \dim_set_eq:NN \l__column_target_dim \linewidth \fp_set:Nn \l__column_target_fp { \linewidth } } { \dim_set:Nn \l__column_target_dim { \l_tmpa_tl } \fp_set:Nn \l__column_target_fp { \l_tmpa_tl } } \prop_clear:N \l__column_coefficient_prop \prop_clear:N \l__column_natural_width_prop \prop_clear:N \l__column_computed_width_prop \PackageError{test} { linewidth:~ dim~ \dim_use:N \l__column_target_dim,~ fp~ \fp_use:N \l__column_target_fp }{}% \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl { \tl_set:Nx \l__tblr_a_tl { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { width } } \tl_set:Nx \l__tblr_b_tl { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { coefficient } } \tl_set:Nx \l__tblr_c_tl { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { @col-width } } \dim_compare:nNnTF { \l__tblr_a_tl } < { 0pt } % column width unset { \dim_compare:nNnTF { \l__tblr_b_tl pt } = { 0pt } { \dim_sub:Nn \l__column_target_dim { \l__tblr_c_tl } \fp_sub:Nn \l__column_target_fp { \l__tblr_c_tl } } { \prop_put:Nxx \l__column_coefficient_prop { \l__tblr_j_tl } { \l__tblr_b_tl } \prop_put:Nxn \l__column_computed_width_prop { \l__tblr_j_tl } { 0pt } \dim_compare:nNnF { \l__tblr_b_tl pt } > { 0pt } { \prop_put:Nxx \l__column_natural_width_prop { \l__tblr_j_tl } { \l__tblr_c_tl } } } } { \dim_sub:Nn \l__column_target_dim { \l__tblr_a_tl } \fp_sub:Nn \l__column_target_fp { \l__tblr_a_tl } } \tl_set:Nx \l__tblr_a_tl { \__tblr_spec_item:ne { vline } { [\l__tblr_j_tl] / @vline-width } } \tl_set:Nx \l__tblr_b_tl { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { leftsep } } \tl_set:Nx \l__tblr_c_tl { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { rightsep } } \dim_sub:Nn \l__column_target_dim { \l__tblr_a_tl + \l__tblr_b_tl + \l__tblr_c_tl } \fp_sub:Nn \l__column_target_fp { \l__tblr_a_tl + \l__tblr_b_tl + \l__tblr_c_tl } \PackageError{test} { remaining~ width:~ dim~ \dim_use:N \l__column_target_dim,~ fp~ \fp_use:N \l__column_target_fp }{}% } \tl_set:Nx \l__tblr_a_tl { \__tblr_spec_item:ne { vline } { [\int_eval:n {\c@colcount + 1}] / @vline-width } } \tl_if_empty:NF \l__tblr_a_tl { \dim_sub:Nn \l__column_target_dim { \l__tblr_a_tl } \fp_sub:Nn \l__column_target_fp { \l__tblr_a_tl } } % use fp calculation result \dim_set:Nn \l__column_target_dim { \fp_to_dim:N \l__column_target_fp } \LogTblrTracing { target } } \ExplSyntaxOff \makeatother \begin{document} \def\test#1{\par Column width = #1, expandable columns with full line width: \begin{center} \begin{tblr}{colspec = {Q[l,#1]X[c]X[c]}, width=\linewidth, % 345pt hlines, vlines } A1 & B1 & C1 \\ \end{tblr} \end{center} } \test{20mm} \test{56.9055pt} \end{document} ```
In log
! Package test Error: linewidth: dim 345.0pt, fp 345.
! Package test Error: remaining width: dim 275.6945pt, fp 275.6945.
! Package test Error: remaining width: dim 263.29451pt, fp 263.2945.
! Package test Error: remaining width: dim 250.89452pt, fp 250.8945.
Thanks for the explanation and the local fix!
Do you consider updating this in the MacTeX distribution?
Note fp arithmetic is two orders of magnitude slower than dim arithmetic. Perhaps tabularray
wants to introduce a new boolean option like accurate=true|false
, in order to change more dim arithmetic to fp.
\documentclass{article}
\usepackage{l3benchmark}
\ExplSyntaxOn
\dim_set:Nn \l_tmpa_dim {100pt}
\fp_set:Nn \l_tmpa_fp {100pt}
\benchmark:n { \dim_sub:Nn \l_tmpa_dim {.4pt} } % 4.71e-7 seconds (2 ops)
\benchmark:n { \fp_sub:Nn \l_tmpa_fp {.4pt} } % 7.56e-5 seconds (308 ops)
\ExplSyntaxOff
\begin{document}
\end{document}
Do you consider updating this in the MacTeX distribution?
@FloMiLe I'm not the package author nor maintainer so... . According to repo wiki, the next scheduled release date is 2023-09-01 (2023b), see https://github.com/lvjr/tabularray/wiki/ChangeLog#2023-09-01-version-2023b.
Note fp arithmetic is two orders of magnitude slower than dim arithmetic. Perhaps
tabularray
wants to introduce a new boolean option likeaccurate=true|false
, in order to change more dim arithmetic to fp.
@muzimuzhi The interface looks good. If you are interested in solving this issue, just do it and commit the change. Same for other issues.
The default width of a table with extendable columns is
\linewidth
. However, I think that the actual width is ever so slightly larger when the width of a fixed-width column is given in mm. When I place such a table inside acenter
environment (out of habit, but especially) for nice vertical gaps, an increased vertical space above the table signals that the table is actually wider than `\linewidth'.The code in this MWE
produces the following result:
Can you confirm this behavior?