summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/siunitx/siunitx-number.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/siunitx/siunitx-number.dtx')
-rw-r--r--macros/latex/contrib/siunitx/siunitx-number.dtx184
1 files changed, 163 insertions, 21 deletions
diff --git a/macros/latex/contrib/siunitx/siunitx-number.dtx b/macros/latex/contrib/siunitx/siunitx-number.dtx
index 38db10d71b..924aaa3b0f 100644
--- a/macros/latex/contrib/siunitx/siunitx-number.dtx
+++ b/macros/latex/contrib/siunitx/siunitx-number.dtx
@@ -807,6 +807,11 @@
{
\group_begin:
\tl_clear:N \l_@@_parsed_tl
+ \tl_map_inline:Nn \l_@@_input_ignore_tl
+ {
+ \token_if_macro:NT ##1
+ { \cs_set_eq:NN ##1 \scan_stop: }
+ }
\protected@edef \l_@@_arg_tl
{
\bool_if:NTF \l_@@_expression_bool
@@ -815,9 +820,8 @@
}
\tl_set_eq:NN \l_@@_input_tl \l_@@_arg_tl
\siunitx_number_normalize_symbols:N \l_@@_arg_tl
- \protected@edef \l_@@_input_ignore_tl { \l_@@_input_ignore_tl }
- \tl_if_empty:NF \l_@@_input_ignore_tl
- { \tl_remove_all:NV \l_@@_arg_tl \l_@@_input_ignore_tl }
+ \tl_map_inline:Nn \l_@@_input_ignore_tl
+ { \tl_remove_all:Nn \l_@@_arg_tl {##1} }
\tl_if_empty:NF \l_@@_arg_tl
{ \@@_parse_comparator: }
\@@_parse_check:
@@ -2201,6 +2205,9 @@
% \begin{macro}[EXP]{\@@_round_auxvi:nN}
% \begin{macro}[EXP]{\@@_round_auxvii:nnN, \@@_round_auxviii:nnN}
% \begin{macro}[EXP]{\@@_round_final_integer:nnw, \@@_round_final_decimal:nnw}
+% \begin{macro}[EXP]{\@@_round_final_signicant:n}
+% \begin{macro}[EXP]{\@@_round_final_signicant:N}
+% \begin{macro}[EXP]{\@@_round_final_signicant:w}
% \begin{macro}[EXP]{\@@_round_final_output:nn, \@@_round_final_output:ff}
% \begin{macro}[EXP]{\@@_round_final:nn, \@@_round_final:fn}
% \begin{macro}[EXP]{\@@_round_final_shift:nn, \@@_round_final_shift:ff}
@@ -2259,7 +2266,10 @@
% one of which deals with the integer. In the latter, we should never hit
% the end before we've dropped all the digits: the fixed-zero is a
% fall-back in case something weird happens. For the integer case, we need
-% to collect up zeros to pad the length back out correctly later.
+% to collect up zeros to pad the length back out correctly later. We also
+% have to cover the case where we round to exactly place above the length
+% of the integer: that may product a value of $1\dots$: we tidy up the
+% case where it comes out as $0$ later.
% \begin{macrocode}
\cs_new:Npn \@@_round_auxiii:nnnN #1#2#3#4
{
@@ -2278,13 +2288,20 @@
\cs_new:Npn \@@_round_auxiv:nnnN #1#2#3#4
{
\quark_if_recursion_tail_stop_do:Nn #4
- { { 0 } { } }
+ {
+ \int_compare:nNnTF {#1} = 0
+ {
+ \@@_round_auxvi:nnN {#3} {#2}
+ 0 \q_recursion_tail \q_recursion_stop
+ }
+ { { 0 } { } }
+ }
\int_compare:nNnTF {#1} > 0
{
\exp_args:Nf \@@_round_auxiv:nnnN
{ \int_eval:n { #1 - 1 } } { #2 0 } { #4#3 }
}
- { \@@_round_auxvi:nnnN {#3} {#2} #4 }
+ { \@@_round_auxvi:nnN {#3} {#2} #4 }
}
% \end{macrocode}
% The lead off to rounding proper needs to deal with the half-even rule:
@@ -2312,7 +2329,7 @@
{ \@@_round_auxvii:nnN }
{#2} { } #3
}
-\cs_new:Npn \@@_round_auxvi:nnnN #1#2#3
+\cs_new:Npn \@@_round_auxvi:nnN #1#2#3
{
\quark_if_recursion_tail_stop_do:Nn #3
{ { 0 } { } }
@@ -2409,9 +2426,27 @@
#1#2#3 \q_recursion_tail \q_recursion_stop
{
\@@_round_final_output:ff
- { \tl_reverse:n {#3} #2 }
+ { \exp_args:Ne \@@_round_final_significant:n { \tl_reverse:n {#3} #2 } }
{#1}
}
+\cs_new:Npn \@@_round_final_significant:n #1
+ {
+ \@@_round_final_significant:N #1
+ \q_recursion_tail \q_recursion_stop
+ }
+\cs_new:Npn \@@_round_final_significant:N #1
+ {
+ \quark_if_recursion_tail_stop_do:Nn #1 { 0 }
+ \int_compare:nNnTF {#1} = 0
+ { \@@_round_final_significant:N }
+ {
+ #1
+ \@@_round_final_significant:w
+ }
+ }
+\cs_new:Npn \@@_round_final_significant:w
+ #1 \q_recursion_tail \q_recursion_stop
+ {#1}
\cs_new:Npn \@@_round_final_output:nn #1#2 { {#1} {#2} }
\cs_generate_variant:Nn \@@_round_final_output:nn { ff }
\cs_new:Npn \@@_round_final:nn #1#2
@@ -2442,7 +2477,6 @@
\int_compare:nNnTF { \tl_count:n {#1} } = 4
{
\@@_round_engineering:NNNNn #1 {#2}
- { }
\@@_round_final_shift:Nw 3
}
{ {#1} {#2} }
@@ -2467,11 +2501,13 @@
{
\@@_exponent_shift:nnf
{ 1 } {#1} { \@@_round_truncate_direct:n {#2} }
- { }
\@@_round_final_shift:Nw 1
}
-\cs_new:Npn \@@_round_final_shift:Nw #1#2 \@@_round_places_end:nn #3#4
- { \@@_exponent_finalise:n { #3#4 + #1 } }
+\cs_new:Npn \@@_round_final_shift:Nw #1#2 \@@_round_places_end:nnn #3#4#5
+ {
+ \exp_not:n { {#3} }
+ \@@_exponent_finalise:n { #4#5 + #1 }
+ }
% \end{macrocode}
% When we have rounded up to the next power of ten, we need to go back and
% remove one more digit. That only happens when rounding to a number of
@@ -2509,6 +2545,9 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}[EXP]{\@@_round_if_half_p:n}
% \begin{macro}[EXP]{\@@_round_if_half:N}
@@ -2622,7 +2661,7 @@
% \end{macro}
%
% \begin{macro}[EXP]{\@@_round_places:nnnnnnn}
-% \begin{macro}[EXP]{\@@_round_places_end:nn}
+% \begin{macro}[EXP]{\@@_round_places_end:nnn}
% \begin{macro}[EXP]{\@@_round_places_decimal:nn, \@@_round_places_integer:nn}
% \begin{macro}[EXP]{\@@_round_places_finalise:n}
% \begin{macro}[EXP]{\@@_round_places_finalise:nnnnnnn}
@@ -2644,12 +2683,12 @@
{ \@@_round_places_decimal:nn }
{ \@@_round_places_integer:nn }
{#3} {#4}
- \@@_round_places_end:nn {#6} {#7}
+ \@@_round_places_end:nnn { } {#6} {#7}
}
}
{ \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } }
}
-\cs_new:Npn \@@_round_places_end:nn #1#2 { { } \exp_not:n { {#1} {#2} } }
+\cs_new:Npn \@@_round_places_end:nnn #1#2#3 { \exp_not:n { {#1} {#2} {#3} } }
\cs_new:Npn \@@_round_places_decimal:nn #1#2
{
\int_compare:nNnTF
@@ -2724,9 +2763,26 @@
% \end{macro}
%
% \begin{macro}[EXP]{\@@_round_uncertainty:nnnnnnn}
+% \begin{macro}[EXP]{\@@_round_uncertainty_end:nn}
% \begin{macro}[EXP]{\@@_round_uncertainty:nnn}
% \begin{macro}[EXP]{\@@_round_uncertainty:nnnnn, \@@_round_uncertainty_aux:nnnnn}
% \begin{macro}[EXP]{\@@_round_uncertainty_aux:nnnnnn}
+% \begin{macro}[EXP]{\@@_round_uncertainty_shift:nn}
+% \begin{macro}[EXP]{\@@_round_uncertainty_shift:nnnw}
+% \begin{macro}[EXP]{\@@_round_uncertainty_shift:nnnn}
+% \begin{macro}[EXP]
+% {
+% \@@_round_uncertainty_engineering:nnn ,
+% \@@_round_uncertainty_fixed:nnn ,
+% \@@_round_uncertainty_input:nnn ,
+% \@@_round_uncertainty_scientific:nnn
+% }
+% \begin{macro}[EXP]
+% {
+% \@@_round_uncertainty_engineering_2:n ,
+% \@@_round_uncertainty_engineering_3:n ,
+% \@@_round_uncertainty_engineering_4:n
+% }
% Rounding to an uncertainty can only happen where the result will have some
% uncertainty left: otherwise we simply drop the uncertainty entirely. Only
% |S|-type uncertainties can be used for rounding.
@@ -2736,18 +2792,20 @@
\bool_lazy_or:nnTF
{ \tl_if_blank_p:n {#5} }
{ ! \int_compare_p:nNn \l_@@_round_precision_int > 0 }
- { \exp_not:n { {#1} #2 {#3} {#4} { } #6 {#7} } }
+ { \exp_not:n { {#1} {#2} {#3} {#4} { } {#6} {#7} } }
{
\str_if_eq:eeTF { \tl_head:n {#5} } { S }
{
\exp_not:n { {#1} {#2} }
\exp_args:Nnno \@@_round_uncertainty:nnn
{#3} {#4} { \use_ii:nn #5 }
- \exp_not:n { {#6} {#7} }
+ \@@_round_uncertainty_end:nn {#6} {#7}
}
{ \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } }
}
}
+\cs_new:Npn \@@_round_uncertainty_end:nn #1#2
+ { \exp_not:n { {#1} {#2} } }
% \end{macrocode}
% Round the uncertainty first: this is needed to get the number of places
% correct (for the case where the uncertainty rounds up to |1...|). Once that
@@ -2796,13 +2854,97 @@
{ { S } { #4 #1 } }
}
{
- \@@_round:fnn
- { \int_eval:n { #2 + 1 } }
- {#5} {#6}
- { { S } { #3 \@@_round_truncate_direct:n {#4} #1 } }
+ \exp_args:Ne \@@_round_uncertainty_shift:nn
+ {
+ \@@_round:fnn
+ { \int_eval:n { #2 + 1 } }
+ {#5} {#6}
+ }
+ { { S } { #3 #1 } }
}
}
% \end{macrocode}
+% We now have to clear up the exponent, plus deal with the case where
+% rounding has resulted in the entire value being uncertain (|1(1)| with
+% some exponent). The latter shows up if the uncertainty is too long or if
+% we match a specific pattern.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_uncertainty_shift:nn #1#2
+ { \@@_round_uncertainty_shift:nnnw #1 {#2} }
+\cs_new:Npn \@@_round_uncertainty_shift:nnnw
+ #1#2#3 #4 \@@_round_uncertainty_end:nn #5#6
+ {
+ #4
+ \bool_lazy_and:nnTF
+ {
+ \int_compare_p:nNn
+ { \tl_count:o { \use_ii:nn #3 } } = \l_@@_round_precision_int
+ }
+ {
+ ! \str_if_eq_p:nn { {#1} {#2} {#3} } { { 10 } { } { { S } { 1 } } }
+ }
+ {
+ \use:c
+ { @@_round_ \l_@@_exponent_mode_tl :nn }
+ {#1} {#2}
+ \@@_round_places_end:nnn {#3} {#5} {#6}
+ }
+ {
+ \use:c
+ { @@_round_uncertainty_ \l_@@_exponent_mode_tl :nnn }
+ {#1} {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% With the data available, adjust the output such that the uncertainty
+% is of the right length.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_uncertainty_engineering:nnn #1#2#3
+ {
+ \use:c
+ {
+ @@_round_uncertainty_
+ \l_@@_exponent_mode_tl _
+ \tl_count:n {#1}
+ :n
+ }
+ {#2#3}
+ }
+\cs_new:cpn { @@_round_uncertainty_engineering_2:n } #1
+ {
+ { 10 } { } { { S } { 10 } }
+ \@@_exponent_finalise:n {#1}
+ }
+\cs_new:cpn { @@_round_uncertainty_engineering_3:n } #1
+ {
+ { 100 } { } { { S } { 100 } }
+ \@@_exponent_finalise:n {#1}
+ }
+\cs_new:cpn { @@_round_uncertainty_engineering_4:n } #1
+ {
+ { 1 } { } { { S } { 1 } }
+ \@@_exponent_finalise:n { #1 + 3 }
+ }
+\cs_new:Npn \@@_round_uncertainty_fixed:nnn #1#2#3
+ {
+ {#1} { }
+ { { S } { 1 \prg_replicate:nn { \tl_count:n {#1} - 1 } { 0 } } }
+ {#2} {#3}
+ }
+\cs_new_eq:NN \@@_round_uncertainty_input:nnn
+ \@@_round_uncertainty_fixed:nnn
+\cs_new:Npn \@@_round_uncertainty_scientific:nnn #1#2#3
+ {
+ { 1 } { } { { S } { 1 } }
+ \@@_exponent_finalise:n { #2#3 + \tl_count:n {#1} - 1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}