%% %% This is file `l3fp.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% l3fp.dtx (with options: `package') %% l3fp-aux.dtx (with options: `package') %% l3fp-traps.dtx (with options: `package') %% l3fp-round.dtx (with options: `package') %% l3fp-parse.dtx (with options: `package') %% l3fp-logic.dtx (with options: `package') %% l3fp-basics.dtx (with options: `package') %% l3fp-extended.dtx (with options: `package') %% l3fp-expo.dtx (with options: `package') %% l3fp-trig.dtx (with options: `package') %% l3fp-convert.dtx (with options: `package') %% l3fp-assign.dtx (with options: `package') %% l3fp-old.dtx (with options: `package') %% %% EXPERIMENTAL CODE %% %% Do not distribute this file without also distributing the %% source files specified above. %% %% Do not distribute a modified version of this file. %% %% File: l3fp.dtx Copyright (C) 2011-2014 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX3 Project Team. %% %% ----------------------------------------------------------------------- %% \RequirePackage{l3bootstrap} \GetIdInfo$Id: l3fp.dtx 4642 2014-01-04 17:28:32Z joseph $ {L3 Floating points} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \__expl_package_check: %% File: l3fp-aux.dtx Copyright(C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new:Npn \__fp_use_none_stop_f:n #1 { \exp_stop_f: } \cs_new:Npn \__fp_use_s:n #1 { #1; } \cs_new:Npn \__fp_use_s:nn #1#2 { #1#2; } \cs_new:Npn \__fp_use_none_until_s:w #1; { } \cs_new:Npn \__fp_use_i_until_s:nw #1#2; {#1} \cs_new:Npn \__fp_use_ii_until_s:nnw #1#2#3; {#2} \cs_new:Npn \__fp_reverse_args:Nww #1 #2; #3; { #1 #3; #2; } \cs_new:Npn \__fp_rrot:www #1; #2; #3; { #2; #3; #1; } \cs_new:Npn \__fp_use_i:ww #1; #2; { #1; } \cs_new:Npn \__fp_use_i:www #1; #2; #3; { #1; } \__scan_new:N \s__fp \cs_new_protected:Npn \__fp_chk:w #1 ; { \__msg_kernel_error:nnx { kernel } { misused-fp } { \fp_to_tl:n { \s__fp \__fp_chk:w #1 ; } } } \__scan_new:N \s__fp_mark \__scan_new:N \s__fp_stop \__scan_new:N \s__fp_invalid \__scan_new:N \s__fp_underflow \__scan_new:N \s__fp_overflow \__scan_new:N \s__fp_division \__scan_new:N \s__fp_exact \tl_const:Nn \c_zero_fp { \s__fp \__fp_chk:w 0 0 \s__fp_exact ; } \tl_const:Nn \c_minus_zero_fp { \s__fp \__fp_chk:w 0 2 \s__fp_exact ; } \tl_const:Nn \c_inf_fp { \s__fp \__fp_chk:w 2 0 \s__fp_exact ; } \tl_const:Nn \c_minus_inf_fp { \s__fp \__fp_chk:w 2 2 \s__fp_exact ; } \tl_const:Nn \c_nan_fp { \s__fp \__fp_chk:w 3 1 \s__fp_exact ; } \int_const:Nn \c__fp_max_exponent_int { 10000 } \cs_new:Npn \__fp_zero_fp:N #1 { \s__fp \__fp_chk:w 0 #1 \s__fp_underflow ; } \cs_new:Npn \__fp_inf_fp:N #1 { \s__fp \__fp_chk:w 2 #1 \s__fp_overflow ; } \cs_new:Npn \__fp_min_fp:N #1 { \s__fp \__fp_chk:w 1 #1 { \int_eval:n { - \c__fp_max_exponent_int } } {1000} {0000} {0000} {0000} ; } \cs_new:Npn \__fp_max_fp:N #1 { \s__fp \__fp_chk:w 1 #1 { \int_use:N \c__fp_max_exponent_int } {9999} {9999} {9999} {9999} ; } \cs_new:Npn \__fp_exponent:w \s__fp \__fp_chk:w #1 { \if_meaning:w 1 #1 \exp_after:wN \__fp_use_ii_until_s:nnw \else: \exp_after:wN \__fp_use_i_until_s:nw \exp_after:wN 0 \fi: } \cs_new:Npn \__fp_neg_sign:N #1 { \__int_eval:w \c_two - #1 \__int_eval_end: } \cs_new:Npn \__fp_sanitize:Nw #1 #2; { \if_case:w \if_int_compare:w #2 > \c__fp_max_exponent_int \c_one \else: \if_int_compare:w #2 < - \c__fp_max_exponent_int \c_two \else: \if_meaning:w 1 #1 \c_three \else: \c_zero \fi: \fi: \fi: \or: \exp_after:wN \__fp_overflow:w \or: \exp_after:wN \__fp_underflow:w \or: \exp_after:wN \__fp_sanitize_zero:w \fi: \s__fp \__fp_chk:w 1 #1 {#2} } \cs_new:Npn \__fp_sanitize:wN #1; #2 { \__fp_sanitize:Nw #2 #1; } \cs_new:Npn \__fp_sanitize_zero:w \s__fp \__fp_chk:w #1 #2 #3; { \c_zero_fp } \cs_new:Npn \__fp_exp_after_o:w \s__fp \__fp_chk:w #1 { \if_meaning:w 1 #1 \exp_after:wN \__fp_exp_after_normal:nNNw \else: \exp_after:wN \__fp_exp_after_special:nNNw \fi: { } #1 } \cs_new:Npn \__fp_exp_after_o:nw #1 \s__fp \__fp_chk:w #2 { \if_meaning:w 1 #2 \exp_after:wN \__fp_exp_after_normal:nNNw \else: \exp_after:wN \__fp_exp_after_special:nNNw \fi: { #1 } #2 } \cs_new:Npn \__fp_exp_after_f:nw #1 \s__fp \__fp_chk:w #2 { \if_meaning:w 1 #2 \exp_after:wN \__fp_exp_after_normal:nNNw \else: \exp_after:wN \__fp_exp_after_special:nNNw \fi: { \tex_romannumeral:D -`0 #1 } #2 } \cs_new:Npn \__fp_exp_after_special:nNNw #1#2#3#4; { \exp_after:wN \s__fp \exp_after:wN \__fp_chk:w \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 \exp_after:wN ; #1 } \cs_new:Npn \__fp_exp_after_normal:nNNw #1 1 #2 #3 #4#5#6#7; { \exp_after:wN \__fp_exp_after_normal:Nwwwww \exp_after:wN #2 \__int_value:w #3 \exp_after:wN ; \__int_value:w 1 #4 \exp_after:wN ; \__int_value:w 1 #5 \exp_after:wN ; \__int_value:w 1 #6 \exp_after:wN ; \__int_value:w 1 #7 \exp_after:wN ; #1 } \cs_new:Npn \__fp_exp_after_normal:Nwwwww #1 #2; 1 #3 ; 1 #4 ; 1 #5 ; 1 #6 ; { \s__fp \__fp_chk:w 1 #1 {#2} {#3} {#4} {#5} {#6} ; } \cs_new:Npn \__fp_exp_after_array_f:w #1 { \cs:w __fp_exp_after \__fp_type_from_scan:N #1 _f:nw \cs_end: { \__fp_exp_after_array_f:w } #1 } \cs_new_eq:NN \__fp_exp_after_stop_f:nw \use_none:nn \int_const:Nn \c__fp_leading_shift_int { - 5 0000 } \int_const:Nn \c__fp_middle_shift_int { 5 0000 * 9999 } \int_const:Nn \c__fp_trailing_shift_int { 5 0000 * 10000 } \cs_new:Npn \__fp_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} } \int_const:Nn \c__fp_big_leading_shift_int { - 15 2374 } \int_const:Nn \c__fp_big_middle_shift_int { 15 2374 * 9999 } \int_const:Nn \c__fp_big_trailing_shift_int { 15 2374 * 10000 } \cs_new:Npn \__fp_pack_big:NNNNNNw #1#2 #3#4#5#6 #7; { + #1#2#3#4#5#6 ; {#7} } \int_const:Nn \c__fp_Bigg_leading_shift_int { - 20 0000 } \int_const:Nn \c__fp_Bigg_middle_shift_int { 20 0000 * 9999 } \int_const:Nn \c__fp_Bigg_trailing_shift_int { 20 0000 * 10000 } \cs_new:Npn \__fp_pack_Bigg:NNNNNNw #1#2 #3#4#5#6 #7; { + #1#2#3#4#5#6 ; {#7} } \cs_new:Npn \__fp_pack_twice_four:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9 { #1 {#2#3#4#5} {#6#7#8#9} ; } \cs_new:Npn \__fp_pack_eight:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9 { #1 {#2#3#4#5#6#7#8#9} ; } \cs_new:Npn \__fp_decimate:nNnnnn #1 { \cs:w __fp_decimate_ \if_int_compare:w \__int_eval:w #1 > \c_sixteen tiny \else: \tex_romannumeral:D \__int_eval:w #1 \fi: :Nnnnn \cs_end: } \cs_new:Npn \__fp_decimate_:Nnnnn #1 #2#3#4#5 { #1 0 {#2#3} {#4#5} ; } \cs_new:Npn \__fp_decimate_tiny:Nnnnn #1 #2#3#4#5 { #1 1 { 0000 0000 } { 0000 0000 } 0 #2#3#4#5 ; } \cs_new:Npn \__fp_tmp:w #1 #2 #3 { \cs_new:cpn { __fp_decimate_ #1 :Nnnnn } ##1 ##2##3##4##5 { \exp_after:wN ##1 \__int_value:w \exp_after:wN \__fp_round_digit:Nw #2 ; \__fp_decimate_pack:nnnnnnnnnnw #3 ; } } \__fp_tmp:w {i} {\use_none:nnn #50} { 0{#2}#3{#4}#5 } \__fp_tmp:w {ii} {\use_none:nn #5 } { 00{#2}#3{#4}#5 } \__fp_tmp:w {iii} {\use_none:n #5 } { 000{#2}#3{#4}#5 } \__fp_tmp:w {iv} { #5 } { {0000}#2{#3}#4 #5 } \__fp_tmp:w {v} {\use_none:nnn #4#5 } { 0{0000}#2{#3}#4 #5 } \__fp_tmp:w {vi} {\use_none:nn #4#5 } { 00{0000}#2{#3}#4 #5 } \__fp_tmp:w {vii} {\use_none:n #4#5 } { 000{0000}#2{#3}#4 #5 } \__fp_tmp:w {viii}{ #4#5 } { {0000}0000{#2}#3 #4 #5 } \__fp_tmp:w {ix} {\use_none:nnn #3#4+#5} { 0{0000}0000{#2}#3 #4 #5 } \__fp_tmp:w {x} {\use_none:nn #3#4+#5} { 00{0000}0000{#2}#3 #4 #5 } \__fp_tmp:w {xi} {\use_none:n #3#4+#5} { 000{0000}0000{#2}#3 #4 #5 } \__fp_tmp:w {xii} { #3#4+#5} { {0000}0000{0000}#2 #3 #4 #5 } \__fp_tmp:w {xiii}{\use_none:nnn#2#3+#4#5} { 0{0000}0000{0000}#2 #3 #4 #5 } \__fp_tmp:w {xiv} {\use_none:nn #2#3+#4#5} { 00{0000}0000{0000}#2 #3 #4 #5 } \__fp_tmp:w {xv} {\use_none:n #2#3+#4#5} { 000{0000}0000{0000}#2 #3 #4 #5 } \__fp_tmp:w {xvi} { #2#3+#4#5} {{0000}0000{0000}0000 #2 #3 #4 #5 } \cs_new:Npn \__fp_decimate_pack:nnnnnnnnnnw #1#2#3#4#5 { \__fp_decimate_pack:nnnnnnw { #1#2#3#4#5 } } \cs_new:Npn \__fp_decimate_pack:nnnnnnw #1 #2#3#4#5#6 { {#1} {#2#3#4#5#6} } \cs_new:Npn \__fp_case_use:nw #1#2 \fi: #3 \s__fp { \fi: #1 \s__fp } \cs_new:Npn \__fp_case_return:nw #1#2 \fi: #3 ; { \fi: #1 } \cs_new:Npn \__fp_case_return_o:Nw #1#2 \fi: #3 \s__fp #4 ; { \fi: \exp_after:wN #1 } \cs_new:Npn \__fp_case_return_same_o:w #1 \fi: #2 \s__fp { \fi: \__fp_exp_after_o:w \s__fp } \cs_new:Npn \__fp_case_return_o:Nww #1#2 \fi: #3 \s__fp #4 ; #5 ; { \fi: \exp_after:wN #1 } \cs_new:Npn \__fp_case_return_i_o:ww #1 \fi: #2 \s__fp #3 ; \s__fp #4 ; { \fi: \__fp_exp_after_o:w \s__fp #3 ; } \cs_new:Npn \__fp_case_return_ii_o:ww #1 \fi: #2 \s__fp #3 ; { \fi: \__fp_exp_after_o:w } \cs_new:Npn \__fp_small_int:wTF \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return:nw { \__fp_small_int_true:wTF 0 ; } \or: \exp_after:wN \__fp_small_int_normal:NnwTF \or: \__fp_case_return:nw { \exp_after:wN \__fp_small_int_true:wTF \__int_value:w \if_meaning:w 2 #2 - \fi: 1 0000 0000 ; } \else: \__fp_case_return:nw \use_ii:nn \fi: #2 } \cs_new:Npn \__fp_small_int_true:wTF #1; #2#3 { #2 {#1} } \cs_new:Npn \__fp_small_int_normal:NnwTF #1#2#3; { \if_int_compare:w #2 > \c_zero \__fp_decimate:nNnnnn { \c_sixteen - #2 } \__fp_small_int_test:NnnwNnw #3 #1 {#2} \else: \exp_after:wN \use_iii:nnn \fi: ; } \cs_new:Npn \__fp_small_int_test:NnnwNnw #1#2#3#4; #5#6 { \if_meaning:w 0 #1 \exp_after:wN \__fp_small_int_true:wTF \__int_value:w \if_meaning:w 2 #5 - \fi: \if_int_compare:w #6 > \c_eight 1 0000 0000 \else: #3 \fi: \else: \use_i:nn \fi: } \cs_new:Npn \__fp_array_count:n #1 { \int_use:N \__int_eval:w \c_zero \__fp_array_count_loop:Nw #1 { ? \__prg_break: } ; \__prg_break_point: \__int_eval_end: } \cs_new:Npn \__fp_array_count_loop:Nw #1#2; { \use_none:n #1 + \c_one \__fp_array_count_loop:Nw } \cs_new:Npn \__fp_expand:n #1 { \__fp_expand_loop:nwnN { } #1 \prg_do_nothing: \s__fp_mark { } \__fp_expand_loop:nwnN \s__fp_mark { } \__fp_use_i_until_s:nw ; } \cs_new:Npn \__fp_expand_loop:nwnN #1#2 \s__fp_mark #3 #4 { \exp_after:wN #4 \tex_romannumeral:D -`0 #2 \s__fp_mark { #3 #1 } #4 } \__msg_kernel_new:nnnn { kernel } { misused-fp } { A~floating~point~with~value~'#1'~was~misused. } { To~obtain~the~value~of~a~floating~point~variable,~use~ '\token_to_str:N \fp_to_decimal:N',~ '\token_to_str:N \fp_to_scientific:N',~or~other~ conversion~functions. } %% %% File: l3fp-traps.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new_protected:Npn \fp_flag_off:n #1 { \cs_set_eq:cN { l__fp_ #1 _flag_token } \tex_undefined:D } \cs_new:Npn \fp_flag_on:n #1 { \exp_args:Nc \use_none:n { l__fp_ #1 _flag_token } } \prg_new_conditional:Npnn \fp_if_flag_on:n #1 { p , T , F , TF } { \if_cs_exist:w l__fp_ #1 _flag_token \cs_end: \prg_return_true: \else: \prg_return_false: \fi: } \cs_new_eq:NN \l__fp_invalid_operation_flag_token \tex_undefined:D \cs_new_eq:NN \l__fp_division_by_zero_flag_token \tex_undefined:D \cs_new_eq:NN \l__fp_overflow_flag_token \tex_undefined:D \cs_new_eq:NN \l__fp_underflow_flag_token \tex_undefined:D \cs_new_protected:Npn \fp_trap:nn #1#2 { \cs_if_exist_use:cF { __fp_trap_#1_set_#2: } { \clist_if_in:nnTF { invalid_operation , division_by_zero , overflow , underflow } {#1} { \__msg_kernel_error:nnxx { kernel } { unknown-fpu-trap-type } {#1} {#2} } { \__msg_kernel_error:nnx { kernel } { unknown-fpu-exception } {#1} } } } \cs_new_protected_nopar:Npn \__fp_trap_invalid_operation_set_error: { \__fp_trap_invalid_operation_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \__fp_trap_invalid_operation_set_flag: { \__fp_trap_invalid_operation_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \__fp_trap_invalid_operation_set_none: { \__fp_trap_invalid_operation_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \__fp_trap_invalid_operation_set:N #1 { \exp_args:Nno \use:n { \cs_set:Npn \__fp_invalid_operation:nnw ##1##2##3; } { #1 \__fp_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3; } } { } \fp_flag_on:n { invalid_operation } ##1 } \exp_args:Nno \use:n { \cs_set:Npn \__fp_invalid_operation_o:Nww ##1##2; ##3; } { #1 \__fp_error:nffn { invalid-ii } { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1} \fp_flag_on:n { invalid_operation } \exp_after:wN \c_nan_fp } \exp_args:Nno \use:n { \cs_set:Npn \__fp_invalid_operation_tl_o:ff ##1##2 } { #1 \__fp_error:nffn { invalid } {##1} {##2} { } \fp_flag_on:n { invalid_operation } \exp_after:wN \c_nan_fp } } \cs_new_protected_nopar:Npn \__fp_trap_division_by_zero_set_error: { \__fp_trap_division_by_zero_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \__fp_trap_division_by_zero_set_flag: { \__fp_trap_division_by_zero_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \__fp_trap_division_by_zero_set_none: { \__fp_trap_division_by_zero_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \__fp_trap_division_by_zero_set:N #1 { \exp_args:Nno \use:n { \cs_set:Npn \__fp_division_by_zero_o:Nnw ##1##2##3; } { #1 \__fp_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3; } } { } \fp_flag_on:n { division_by_zero } \exp_after:wN ##1 } \exp_args:Nno \use:n { \cs_set:Npn \__fp_division_by_zero_o:NNww ##1##2##3; ##4; } { #1 \__fp_error:nffn { zero-div-ii } { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2} \fp_flag_on:n { division_by_zero } \exp_after:wN ##1 } } \cs_new_protected_nopar:Npn \__fp_trap_overflow_set_error: { \__fp_trap_overflow_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \__fp_trap_overflow_set_flag: { \__fp_trap_overflow_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \__fp_trap_overflow_set_none: { \__fp_trap_overflow_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \__fp_trap_overflow_set:N #1 { \__fp_trap_overflow_set:NnNn #1 { overflow } \__fp_inf_fp:N { inf } } \cs_new_protected_nopar:Npn \__fp_trap_underflow_set_error: { \__fp_trap_underflow_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \__fp_trap_underflow_set_flag: { \__fp_trap_underflow_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \__fp_trap_underflow_set_none: { \__fp_trap_underflow_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \__fp_trap_underflow_set:N #1 { \__fp_trap_overflow_set:NnNn #1 { underflow } \__fp_zero_fp:N { 0 } } \cs_new_protected:Npn \__fp_trap_overflow_set:NnNn #1#2#3#4 { \exp_args:Nno \use:n { \cs_set:cpn { __fp_ #2 :w } \s__fp \__fp_chk:w ##1##2##3; } { #1 \__fp_error:nffn { flow \if_meaning:w 1 ##1 -to \fi: } { \fp_to_tl:n { \s__fp \__fp_chk:w ##1##2##3; } } { \token_if_eq_meaning:NNF 0 ##2 { - } #4 } {#2} \fp_flag_on:n {#2} #3 ##2 } } \cs_new:Npn \__fp_invalid_operation:nnw #1#2#3; { } \cs_new:Npn \__fp_invalid_operation_o:Nww #1#2; #3; { } \cs_new:Npn \__fp_invalid_operation_tl_o:ff #1 #2 { } \cs_new:Npn \__fp_division_by_zero_o:Nnw #1#2#3; { } \cs_new:Npn \__fp_division_by_zero_o:NNww #1#2#3; #4; { } \cs_new:Npn \__fp_overflow:w { } \cs_new:Npn \__fp_underflow:w { } \fp_trap:nn { invalid_operation } { error } \fp_trap:nn { division_by_zero } { flag } \fp_trap:nn { overflow } { flag } \fp_trap:nn { underflow } { flag } \cs_new_nopar:Npn \__fp_invalid_operation_o:nw { \__fp_invalid_operation:nnw { \exp_after:wN \c_nan_fp } } \cs_generate_variant:Nn \__fp_invalid_operation_o:nw { f } \cs_new:Npn \__fp_error:nnnn #1 { \__msg_kernel_expandable_error:nnnnn { kernel } { fp - #1 } } \cs_generate_variant:Nn \__fp_error:nnnn { nnf, nff } \__msg_kernel_new:nnnn { kernel } { unknown-fpu-exception } { The~FPU~exception~'#1'~is~not~known:~that~trap~will~never~be~triggered. } { The~only~exceptions~to~which~traps~can~be~attached~are \\ \iow_indent:n { * ~ invalid_operation \\ * ~ division_by_zero \\ * ~ overflow \\ * ~ underflow } } \__msg_kernel_new:nnnn { kernel } { unknown-fpu-trap-type } { The~FPU~trap~type~'#2'~is~not~known. } { The~trap~type~must~be~one~of \\ \iow_indent:n { * ~ error \\ * ~ flag \\ * ~ none } } \__msg_kernel_new:nnn { kernel } { fp-flow } { An ~ #3 ~ occurred. } \__msg_kernel_new:nnn { kernel } { fp-flow-to } { #1 ~ #3 ed ~ to ~ #2 . } \__msg_kernel_new:nnn { kernel } { fp-zero-div } { Division~by~zero~in~ #1 (#2) } \__msg_kernel_new:nnn { kernel } { fp-zero-div-ii } { Division~by~zero~in~ (#1) #3 (#2) } \__msg_kernel_new:nnn { kernel } { fp-invalid } { Invalid~operation~ #1 (#2) } \__msg_kernel_new:nnn { kernel } { fp-invalid-ii } { Invalid~operation~ (#1) #3 (#2) } %% File: l3fp-round.dtx Copyright(C) 2011-2012 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new:Npn \__fp_round_return_one: { \exp_after:wN \c_one \tex_romannumeral:D } \cs_new:Npn \__fp_round_to_ninf:NNN #1 #2 #3 { \if_meaning:w 2 #1 \if_int_compare:w #3 > \c_zero \__fp_round_return_one: \fi: \fi: \c_zero } \cs_new:Npn \__fp_round_to_zero:NNN #1 #2 #3 { \c_zero } \cs_new:Npn \__fp_round_to_pinf:NNN #1 #2 #3 { \if_meaning:w 0 #1 \if_int_compare:w #3 > \c_zero \__fp_round_return_one: \fi: \fi: \c_zero } \cs_new:Npn \__fp_round_to_nearest:NNN #1 #2 #3 { \if_int_compare:w #3 > \c_five \__fp_round_return_one: \else: \if_meaning:w 5 #3 \if_int_odd:w #2 \exp_stop_f: \__fp_round_return_one: \fi: \fi: \fi: \c_zero } \cs_new_eq:NN \__fp_round:NNN \__fp_round_to_nearest:NNN \cs_new:Npn \__fp_round_s:NNNw #1 #2 #3 #4; { \exp_after:wN \__fp_round:NNN \exp_after:wN #1 \exp_after:wN #2 \int_use:N \__int_eval:w \if_int_odd:w 0 \if_meaning:w 0 #3 1 \fi: \if_meaning:w 5 #3 1 \fi: \exp_stop_f: \if_int_compare:w \__int_eval:w #4 > \c_zero 1 + \fi: \fi: #3 ; } \cs_new:Npn \__fp_round_digit:Nw #1 #2; { \if_int_odd:w \if_meaning:w 0 #1 \c_one \else: \if_meaning:w 5 #1 \c_one \else: \c_zero \fi: \fi: \if_int_compare:w \__int_eval:w #2 > \c_zero \__int_eval:w \c_one + \fi: \fi: #1 } \cs_new:Npn \__fp_round_to_ninf_neg:NNN #1 #2 #3 { \if_meaning:w 0 #1 \if_int_compare:w #3 > \c_zero \__fp_round_return_one: \fi: \fi: \c_zero } \cs_new:Npn \__fp_round_to_zero_neg:NNN #1 #2 #3 { \if_int_compare:w #3 > \c_zero \__fp_round_return_one: \fi: \c_zero } \cs_new:Npn \__fp_round_to_pinf_neg:NNN #1 #2 #3 { \if_meaning:w 2 #1 \if_int_compare:w #3 > \c_zero \__fp_round_return_one: \fi: \fi: \c_zero } \cs_new_eq:NN \__fp_round_to_nearest_neg:NNN \__fp_round_to_nearest:NNN \cs_new_eq:NN \__fp_round_neg:NNN \__fp_round_to_nearest_neg:NNN \cs_new:Npn \__fp_round_o:Nw #1#2 @ { \if_case:w \__int_eval:w \__fp_array_count:n {#2} - \c_one \__int_eval_end: \__fp_round:Nwn #1 #2 {0} \tex_romannumeral:D \or: \__fp_round:Nww #1 #2 \tex_romannumeral:D \else: \__fp_error:nffn { num-args } { \__fp_round_name_from_cs:N #1 () } { 1 } { 2 } \exp_after:wN \c_nan_fp \tex_romannumeral:D \fi: -`0 } \cs_new:Npn \__fp_round_name_from_cs:N #1 { \cs_if_eq:NNTF #1 \__fp_round_to_zero:NNN { trunc } { \cs_if_eq:NNTF #1 \__fp_round_to_ninf:NNN { floor } { \cs_if_eq:NNTF #1 \__fp_round_to_pinf:NNN { ceil } { round } } } } \cs_new:Npn \__fp_round:Nww #1#2 ; #3 ; { \__fp_small_int:wTF #3; { \__fp_round:Nwn #1#2; } { \__fp_invalid_operation_tl_o:ff { \__fp_round_name_from_cs:N #1 } { \__fp_array_to_clist:n { #2; #3; } } } } \cs_new:Npn \__fp_round:Nwn #1 \s__fp \__fp_chk:w #2#3#4; #5 { \if_meaning:w 1 #2 \exp_after:wN \__fp_round_normal:NwNNnw \exp_after:wN #1 \__int_value:w #5 \else: \exp_after:wN \__fp_exp_after_o:w \fi: \s__fp \__fp_chk:w #2#3#4; } \cs_new:Npn \__fp_round_normal:NwNNnw #1#2 \s__fp \__fp_chk:w 1#3#4#5; { \__fp_decimate:nNnnnn { \c_sixteen - #4 - #2 } \__fp_round_normal:NnnwNNnn #5 #1 #3 {#4} {#2} } \cs_new:Npn \__fp_round_normal:NnnwNNnn #1#2#3#4; #5#6 { \exp_after:wN \__fp_round_normal:NNwNnn \int_use:N \__int_eval:w \if_int_compare:w #2 > \c_zero 1 \__int_value:w #2 \exp_after:wN \__fp_round_pack:Nw \int_use:N \__int_eval:w 1#3 + \else: \if_int_compare:w #3 > \c_zero 1 \__int_value:w #3 + \fi: \fi: \exp_after:wN #5 \exp_after:wN #6 \use_none:nnnnnnn #3 #1 \__int_eval_end: 0000 0000 0000 0000 ; #6 } \cs_new:Npn \__fp_round_pack:Nw #1 { \if_meaning:w 2 #1 + \c_one \fi: \__int_eval_end: } \cs_new:Npn \__fp_round_normal:NNwNnn #1 #2 { \if_meaning:w 0 #2 \exp_after:wN \__fp_round_special:NwwNnn \exp_after:wN #1 \fi: \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_round_normal_end:wwNnn ; #2 } \cs_new:Npn \__fp_round_normal_end:wwNnn #1;#2;#3#4#5 { \exp_after:wN \__fp_exp_after_o:w \tex_romannumeral:D -`0 \__fp_sanitize:Nw #3 #4 ; #1 ; } \cs_new:Npn \__fp_round_special:NwwNnn #1#2;#3;#4#5#6 { \if_meaning:w 0 #1 \__fp_case_return:nw { \exp_after:wN \__fp_zero_fp:N \exp_after:wN #4 } \else: \exp_after:wN \__fp_round_special_aux:Nw \exp_after:wN #4 \int_use:N \__int_eval:w \c_one \if_meaning:w 1 #1 -#6 \else: +#5 \fi: \fi: ; } \cs_new:Npn \__fp_round_special_aux:Nw #1#2; { \exp_after:wN \__fp_exp_after_o:w \tex_romannumeral:D -`0 \__fp_sanitize:Nw #1#2; {1000}{0000}{0000}{0000}; } %% File: l3fp-parse.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new:Npn \__fp_parse_expand:w #1 { -`0 #1 } \cs_new:Npn \__fp_parse_return_semicolon:w #1 \fi: \__fp_parse_expand:w { \fi: ; #1 } \group_begin: \char_set_catcode_other:N \S \char_set_catcode_other:N \F \char_set_catcode_other:N \P \char_set_lccode:nn { `\- } { `\_ } \tl_to_lowercase:n { \group_end: \cs_new:Npn \__fp_type_from_scan:N #1 { \exp_after:wN \__fp_type_from_scan:w \token_to_str:N #1 \q_mark S--FP-? \q_mark \q_stop } \cs_new:Npn \__fp_type_from_scan:w #1 S--FP #2 \q_mark #3 \q_stop {#2} } \cs_set_protected:Npn \__fp_tmp:w #1 #2 #3 { \cs_new:cpn { __fp_parse_digits_ #1 :N } ##1 { \if_int_compare:w \c_nine < 1 \token_to_str:N ##1 \exp_stop_f: \token_to_str:N ##1 \exp_after:wN #2 \tex_romannumeral:D \else: \__fp_parse_return_semicolon:w #3 ##1 \fi: \__fp_parse_expand:w } } \__fp_tmp:w {vii} \__fp_parse_digits_vi:N { 0000000 ; 7 } \__fp_tmp:w {vi} \__fp_parse_digits_v:N { 000000 ; 6 } \__fp_tmp:w {v} \__fp_parse_digits_iv:N { 00000 ; 5 } \__fp_tmp:w {iv} \__fp_parse_digits_iii:N { 0000 ; 4 } \__fp_tmp:w {iii} \__fp_parse_digits_ii:N { 000 ; 3 } \__fp_tmp:w {ii} \__fp_parse_digits_i:N { 00 ; 2 } \__fp_tmp:w {i} \__fp_parse_digits_:N { 0 ; 1 } \cs_new_nopar:Npn \__fp_parse_digits_:N { ; ; 0 } \cs_new:Npn \__fp_parse_one:Nw #1 #2 { \if_catcode:w \scan_stop: \exp_not:N #2 \if_meaning:w \scan_stop: #2 \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_one_fp:NN \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_one_register:NN \fi: \else: \if_int_compare:w \c_nine < 1 \token_to_str:N #2 \exp_stop_f: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_one_digit:NN \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_one_other:NN \fi: \fi: #1 #2 } \cs_new:Npn \__fp_parse_one_fp:NN #1#2 { \cs:w __fp_exp_after \__fp_type_from_scan:N #2 _f:nw \cs_end: { \exp_after:wN \__fp_parse_infix:NN \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_expand:w } #2 } \cs_new:Npn \__fp_exp_after_mark_f:nw #1 { \__msg_kernel_expandable_error:nn { kernel } { fp-early-end } \exp_after:wN \c_nan_fp \tex_romannumeral:D -`0 #1 } \cs_new:cpn { __fp_exp_after_?_f:nw } #1#2 { \__msg_kernel_expandable_error:nnn { kernel } { bad-variable } {#2} \exp_after:wN \c_nan_fp \tex_romannumeral:D -`0 #1 } \cs_new:Npn \__fp_parse_one_register:NN #1#2 { \exp_after:wN \__fp_parse_infix_after_operand:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \exp_after:wN \__fp_parse_one_register_aux:Nw \exp_after:wN #2 \__int_value:w \exp_after:wN \__fp_parse_exponent:N \tex_romannumeral:D \__fp_parse_expand:w } \group_begin: \char_set_catcode_other:N \P \char_set_catcode_other:N \T \char_set_catcode_other:N \M \char_set_catcode_other:N \U \tl_to_lowercase:n { \group_end: \cs_new:Npn \__fp_parse_one_register_aux:Nw #1 { \exp_after:wN \use:nn \exp_after:wN \__fp_parse_one_register_auxii:wwwNw \exp_after:wN { \tex_the:D \exp_not:N #1 } ; \__fp_parse_one_register_dim:ww PT ; \__fp_parse_one_register_mu:www . PT ; \__fp_parse_one_register_int:www \q_stop } \cs_new:Npn \__fp_parse_one_register_auxii:wwwNw #1 . #2 PT #3 ; #4#5 \q_stop { #4 #1.#2; } \cs_new:Npn \__fp_parse_one_register_mu:www #1 MU; #2; { \__fp_parse_one_register_dim:ww #1; } } \cs_new:Npn \__fp_parse_one_register_int:www #1; #2.; #3; { \__fp_parse:n { #1 e #3 } } \cs_new:Npn \__fp_parse_one_register_dim:ww #1; #2; { \exp_after:wN \__fp_from_dim_test:ww \__int_value:w #2 \exp_after:wN , \__int_value:w \__dim_eval:w #1 pt ; } \cs_new:Npn \__fp_parse_one_digit:NN #1 { \exp_after:wN \__fp_parse_infix_after_operand:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \exp_after:wN \__fp_sanitize:wN \int_use:N \__int_eval:w \c_zero \__fp_parse_trim_zeros:N } \cs_new:Npn \__fp_parse_one_other:NN #1 #2 { \if_int_compare:w \__int_eval:w ( `#2 \if_int_compare:w `#2 > `Z - \c_thirty_two \fi: ) / 26 = \c_three \exp_after:wN \__fp_parse_word:Nw \exp_after:wN #1 \exp_after:wN #2 \tex_romannumeral:D \exp_after:wN \__fp_parse_letters:N \tex_romannumeral:D \else: \exp_after:wN \__fp_parse_prefix:NNN \exp_after:wN #1 \exp_after:wN #2 \cs:w __fp_parse_prefix_#2:Nw \exp_after:wN \cs_end: \tex_romannumeral:D \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_word:Nw #1#2; { \cs_if_exist_use:cF { __fp_parse_word_#2:N } { \__msg_kernel_expandable_error:nnn { kernel } { unknown-fp-word } {#2} \exp_after:wN \c_nan_fp \tex_romannumeral:D -`0 \__fp_parse_infix:NN } #1 } \cs_new:Npn \__fp_parse_letters:N #1 { -`0 \if_int_compare:w \if_catcode:w \scan_stop: \exp_not:N #1 \c_zero \else: \__int_eval:w ( `#1 \if_int_compare:w `#1 > `Z - \c_thirty_two \fi: ) / 26 \fi: = \c_three \exp_after:wN #1 \tex_romannumeral:D \exp_after:wN \__fp_parse_letters:N \tex_romannumeral:D \else: \__fp_parse_return_semicolon:w #1 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_prefix:NNN #1#2#3 { \if_meaning:w \scan_stop: #3 \exp_after:wN \__fp_parse_prefix_unknown:NNN \exp_after:wN #2 \fi: #3 #1 } \cs_new:Npn \__fp_parse_prefix_unknown:NNN #1#2#3 { \cs_if_exist:cTF { __fp_parse_infix_#1:N } { \__msg_kernel_expandable_error:nnn { kernel } { fp-missing-number } {#1} \exp_after:wN \c_nan_fp \tex_romannumeral:D -`0 \__fp_parse_infix:NN #3 #1 } { \__msg_kernel_expandable_error:nnn { kernel } { fp-unknown-symbol } {#1} \__fp_parse_one:Nw #3 } } \cs_new:Npn \__fp_parse_trim_zeros:N #1 { \if:w 0 \exp_not:N #1 \exp_after:wN \__fp_parse_trim_zeros:N \tex_romannumeral:D \else: \if:w . \exp_not:N #1 \exp_after:wN \__fp_parse_strim_zeros:N \tex_romannumeral:D \else: \__fp_parse_trim_end:w #1 \fi: \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_trim_end:w #1 \fi: \fi: \__fp_parse_expand:w { \fi: \fi: \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: \exp_after:wN \__fp_parse_large:N \else: \exp_after:wN \__fp_parse_zero: \fi: #1 } \cs_new:Npn \__fp_parse_strim_zeros:N #1 { \if:w 0 \exp_not:N #1 - \c_one \exp_after:wN \__fp_parse_strim_zeros:N \tex_romannumeral:D \else: \__fp_parse_strim_end:w #1 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_strim_end:w #1 \fi: \__fp_parse_expand:w { \fi: \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: \exp_after:wN \__fp_parse_small:N \else: \exp_after:wN \__fp_parse_zero: \fi: #1 } \cs_new:Npn \__fp_parse_zero: { \exp_after:wN ; \exp_after:wN 1 \__int_value:w \__fp_parse_exponent:N } \cs_new:Npn \__fp_parse_small:N #1 { \exp_after:wN \__fp_parse_pack_leading:NNNNNww \int_use:N \__int_eval:w 1 \token_to_str:N #1 \exp_after:wN \__fp_parse_small_leading:wwNN \__int_value:w 1 \exp_after:wN \__fp_parse_digits_vii:N \tex_romannumeral:D \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_small_leading:wwNN 1 #1 ; #2; #3 #4 { #1 #2 \exp_after:wN \__fp_parse_pack_trailing:NNNNNNww \exp_after:wN \c_zero \int_use:N \__int_eval:w 1 \if_int_compare:w \c_nine < 1 \token_to_str:N #4 \exp_stop_f: \token_to_str:N #4 \exp_after:wN \__fp_parse_small_trailing:wwNN \__int_value:w 1 \exp_after:wN \__fp_parse_digits_vi:N \tex_romannumeral:D \else: 0000 0000 \__fp_parse_exponent:Nw #4 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_small_trailing:wwNN 1 #1 ; #2; #3 #4 { #1 #2 \if_int_compare:w \c_nine < 1 \token_to_str:N #4 \exp_stop_f: \token_to_str:N #4 \exp_after:wN \__fp_parse_small_round:NN \exp_after:wN #4 \tex_romannumeral:D \else: 0 \__fp_parse_exponent:Nw #4 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_pack_trailing:NNNNNNww #1 #2 #3#4#5#6 #7; #8 ; { \if_meaning:w 2 #2 + \c_one \fi: ; #8 + #1 ; {#3#4#5#6} {#7}; } \cs_new:Npn \__fp_parse_pack_leading:NNNNNww #1 #2#3#4#5 #6; #7; { + #7 \if_meaning:w 2 #1 \__fp_parse_pack_carry:w \fi: ; 0 {#2#3#4#5} {#6} } \cs_new:Npn \__fp_parse_pack_carry:w \fi: ; 0 #1 { \fi: + \c_one ; 0 {1000} } \cs_new:Npn \__fp_parse_large:N #1 { \exp_after:wN \__fp_parse_large_leading:wwNN \__int_value:w 1 \token_to_str:N #1 \exp_after:wN \__fp_parse_digits_vii:N \tex_romannumeral:D \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_large_leading:wwNN 1 #1 ; #2; #3 #4 { + \c_eight - #3 \exp_after:wN \__fp_parse_pack_leading:NNNNNww \int_use:N \__int_eval:w 1 #1 \if_int_compare:w \c_nine < 1 \token_to_str:N #4 \exp_stop_f: \exp_after:wN \__fp_parse_large_trailing:wwNN \__int_value:w 1 \token_to_str:N #4 \exp_after:wN \__fp_parse_digits_vi:N \tex_romannumeral:D \else: \if:w . \exp_not:N #4 \exp_after:wN \__fp_parse_small_leading:wwNN \__int_value:w 1 \cs:w __fp_parse_digits_ \tex_romannumeral:D #3 :N \exp_after:wN \cs_end: \tex_romannumeral:D \else: #2 \exp_after:wN \__fp_parse_pack_trailing:NNNNNNww \exp_after:wN \c_zero \__int_value:w 1 0000 0000 \__fp_parse_exponent:Nw #4 \fi: \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_large_trailing:wwNN 1 #1 ; #2; #3 #4 { \if_int_compare:w \c_nine < 1 \token_to_str:N #4 \exp_stop_f: \exp_after:wN \__fp_parse_pack_trailing:NNNNNNww \exp_after:wN \c_eight \int_use:N \__int_eval:w 1 #1 \token_to_str:N #4 \exp_after:wN \__fp_parse_large_round:NN \exp_after:wN #4 \tex_romannumeral:D \else: \exp_after:wN \__fp_parse_pack_trailing:NNNNNNww \int_use:N \__int_eval:w \c_seven - #3 \exp_stop_f: \int_use:N \__int_eval:w 1 #1 \if:w . \exp_not:N #4 \exp_after:wN \__fp_parse_small_trailing:wwNN \__int_value:w 1 \cs:w __fp_parse_digits_ \tex_romannumeral:D #3 :N \exp_after:wN \cs_end: \tex_romannumeral:D \else: #2 0 \__fp_parse_exponent:Nw #4 \fi: \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_round_loop:N #1 { \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: + \c_one \if:w 0 \token_to_str:N #1 \exp_after:wN \__fp_parse_round_loop:N \tex_romannumeral:D \else: \exp_after:wN \__fp_parse_round_up:N \tex_romannumeral:D \fi: \else: \__fp_parse_return_semicolon:w \c_zero #1 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_round_up:N #1 { \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: + \c_one \exp_after:wN \__fp_parse_round_up:N \tex_romannumeral:D \else: \__fp_parse_return_semicolon:w \c_one #1 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_round_after:wN #1; #2 { + #2 \exp_after:wN ; \int_use:N \__int_eval:w #1 + \__fp_parse_exponent:N } \cs_new:Npn \__fp_parse_small_round:NN #1#2 { \if_int_compare:w \c_nine < 1 \token_to_str:N #2 \exp_stop_f: + \exp_after:wN \__fp_round_s:NNNw \exp_after:wN 0 \exp_after:wN #1 \exp_after:wN #2 \int_use:N \__int_eval:w \exp_after:wN \__fp_parse_round_after:wN \int_use:N \__int_eval:w \c_zero * \__int_eval:w \c_zero \exp_after:wN \__fp_parse_round_loop:N \tex_romannumeral:D \else: \__fp_parse_exponent:Nw #2 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_large_round:NN #1#2 { \if_int_compare:w \c_nine < 1 \token_to_str:N #2 \exp_stop_f: + \exp_after:wN \__fp_round_s:NNNw \exp_after:wN 0 \exp_after:wN #1 \exp_after:wN #2 \int_use:N \__int_eval:w \exp_after:wN \__fp_parse_large_round_aux:wNN \int_use:N \__int_eval:w \c_one \exp_after:wN \__fp_parse_round_loop:N \else: %^^A could be dot, or e, or other \exp_after:wN \__fp_parse_large_round_test:NN \exp_after:wN #1 \exp_after:wN #2 \fi: } \cs_new:Npn \__fp_parse_large_round_test:NN #1#2 { \if:w . \exp_not:N #2 \exp_after:wN \__fp_parse_small_round:NN \exp_after:wN #1 \tex_romannumeral:D \else: \__fp_parse_exponent:Nw #2 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_large_round_aux:wNN #1 ; #2 #3 { + #2 \exp_after:wN \__fp_parse_round_after:wN \int_use:N \__int_eval:w #1 \if:w . \exp_not:N #3 + \c_zero * \__int_eval:w \c_zero \exp_after:wN \__fp_parse_round_loop:N \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN ; \exp_after:wN \c_zero \exp_after:wN #3 \fi: } \cs_new:Npn \__fp_parse_exponent:Nw #1 #2 \__fp_parse_expand:w { \exp_after:wN ; \__int_value:w #2 \__fp_parse_exponent:N #1 } \cs_new:Npn \__fp_parse_exponent:N #1 { \if:w e \exp_not:N #1 \exp_after:wN \__fp_parse_exponent_aux:N \tex_romannumeral:D \else: 0 \__fp_parse_return_semicolon:w #1 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_exponent_aux:N #1 { \if_int_compare:w \if_catcode:w \scan_stop: \exp_not:N #1 \c_zero \else: `#1 \fi: > `9 \exp_stop_f: 0 \exp_after:wN ; \exp_after:wN e \else: \exp_after:wN \__fp_parse_exponent_sign:N \fi: #1 } \cs_new:Npn \__fp_parse_exponent_sign:N #1 { \if:w + \if:w - \exp_not:N #1 + \fi: \token_to_str:N #1 \exp_after:wN \__fp_parse_exponent_sign:N \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN \__fp_parse_exponent_body:N \exp_after:wN #1 \fi: } \cs_new:Npn \__fp_parse_exponent_body:N #1 { \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: \token_to_str:N #1 \exp_after:wN \__fp_parse_exponent_digits:N \tex_romannumeral:D \else: \__fp_parse_exponent_keep:NTF #1 { \__fp_parse_return_semicolon:w #1 } { \exp_after:wN ; \tex_romannumeral:D } \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_exponent_digits:N #1 { \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: \token_to_str:N #1 \exp_after:wN \__fp_parse_exponent_digits:N \tex_romannumeral:D \else: \__fp_parse_return_semicolon:w #1 \fi: \__fp_parse_expand:w } \prg_new_conditional:Npnn \__fp_parse_exponent_keep:N #1 { TF } { \if_catcode:w \scan_stop: \exp_not:N #1 \if_meaning:w \scan_stop: #1 \if_int_compare:w \pdftex_strcmp:D { \s__fp } { \exp_not:N #1 } = \c_zero 0 \__msg_kernel_expandable_error:nnn { kernel } { fp-after-e } { floating~point~ } \prg_return_true: \else: 0 \__msg_kernel_expandable_error:nnn { kernel } { bad-variable } {#1} \prg_return_false: \fi: \else: \if_int_compare:w \pdftex_strcmp:D { \__int_value:w #1 } { \tex_the:D #1 } = \c_zero \__int_value:w #1 \else: 0 \__msg_kernel_expandable_error:nnn { kernel } { fp-after-e } { dimension~#1 } \fi: \prg_return_false: \fi: \else: 0 \__msg_kernel_expandable_error:nnn { kernel } { fp-missing } { exponent } \prg_return_true: \fi: } \cs_new_eq:cN { __fp_parse_prefix_+:Nw } \__fp_parse_one:Nw \cs_new:Npn \__fp_parse_apply_unary:NNNwN #1#2#3#4@#5 { #3 #2 #4 @ \tex_romannumeral:D -`0 #5 #1 } \cs_set_protected:Npn \__fp_tmp:w #1#2#3#4 { \cs_new:cpn { __fp_parse_prefix_ #1 :Nw } ##1 { \exp_after:wN \__fp_parse_apply_unary:NNNwN \exp_after:wN ##1 \exp_after:wN #4 \exp_after:wN #3 \tex_romannumeral:D \if_int_compare:w #2 < ##1 \__fp_parse_operand:Nw ##1 \else: \__fp_parse_operand:Nw #2 \fi: \__fp_parse_expand:w } } \__fp_tmp:w - \c_twelve \__fp_set_sign_o:w 2 \__fp_tmp:w ! \c_twelve \__fp_not_o:w ? \cs_new:cpn { __fp_parse_prefix_.:Nw } #1 { \exp_after:wN \__fp_parse_infix_after_operand:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \exp_after:wN \__fp_sanitize:wN \int_use:N \__int_eval:w \c_zero \__fp_parse_strim_zeros:N } \group_begin: \char_set_catcode_letter:N ( \char_set_catcode_letter:N ) \cs_new:Npn \__fp_parse_prefix_(:Nw #1 { \exp_after:wN \__fp_parse_lparen_after:NwN \exp_after:wN #1 \tex_romannumeral:D \if_int_compare:w #1 = \c_sixteen \__fp_parse_operand:Nw \c_one \else: \__fp_parse_operand:Nw \c_zero \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_lparen_after:NwN #1#2 @ #3 { \token_if_eq_meaning:NNTF #3 \__fp_parse_infix_):N { \__fp_exp_after_array_f:w #2 \s__fp_stop \exp_after:wN \__fp_parse_infix:NN \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_expand:w } { \__msg_kernel_expandable_error:nnn { kernel } { fp-missing } { ) } #2 @ \use_none:n #3 } } \group_end: \cs_set_protected:Npn \__fp_tmp:w #1 #2 { \cs_new_nopar:cpn { __fp_parse_word_#1:N } { \exp_after:wN #2 \tex_romannumeral:D -`0 \__fp_parse_infix:NN } } \__fp_tmp:w { inf } \c_inf_fp \__fp_tmp:w { nan } \c_nan_fp \__fp_tmp:w { pi } \c_pi_fp \__fp_tmp:w { deg } \c_one_degree_fp \__fp_tmp:w { true } \c_one_fp \__fp_tmp:w { false } \c_zero_fp \cs_set_protected:Npn \__fp_tmp:w #1 #2 { \cs_new_nopar:cpn { __fp_parse_word_#1:N } { \__fp_exp_after_f:nw { \__fp_parse_infix:NN } \s__fp \__fp_chk:w 10 #2 ; } } \__fp_tmp:w {pt} { {1} {1000} {0000} {0000} {0000} } \__fp_tmp:w {in} { {2} {7227} {0000} {0000} {0000} } \__fp_tmp:w {pc} { {2} {1200} {0000} {0000} {0000} } \__fp_tmp:w {cm} { {2} {2845} {2755} {9055} {1181} } \__fp_tmp:w {mm} { {1} {2845} {2755} {9055} {1181} } \__fp_tmp:w {dd} { {1} {1070} {0085} {6496} {0630} } \__fp_tmp:w {cc} { {2} {1284} {0102} {7795} {2756} } \__fp_tmp:w {nd} { {1} {1066} {9783} {4645} {6693} } \__fp_tmp:w {nc} { {2} {1280} {3740} {1574} {8031} } \__fp_tmp:w {bp} { {1} {1003} {7500} {0000} {0000} } \__fp_tmp:w {sp} { {-4} {1525} {8789} {0625} {0000} } \tl_map_inline:nn { {em} {ex} } { \cs_new_nopar:cpn { __fp_parse_word_#1:N } { \exp_after:wN \__fp_from_dim_test:ww \exp_after:wN 0 \exp_after:wN , \__int_value:w \__dim_eval:w 1 #1 \exp_after:wN ; \tex_romannumeral:D -`0 \__fp_parse_infix:NN } } \cs_new:Npn \__fp_parse_unary_function:nNN #1#2#3 { \exp_after:wN \__fp_parse_apply_unary:NNNwN \exp_after:wN #3 \exp_after:wN #2 \cs:w __fp_#1_o:w \exp_after:wN \cs_end: \tex_romannumeral:D \__fp_parse_operand:Nw \c_fifteen \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_function:NNN #1#2#3 { \exp_after:wN \__fp_parse_apply_unary:NNNwN \exp_after:wN #3 \exp_after:wN #2 \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_operand:Nw \c_sixteen \__fp_parse_expand:w } \cs_new_nopar:Npn \__fp_parse_word_acot:N { \__fp_parse_function:NNN \__fp_acot_o:Nw \use_i:nn } \cs_new_nopar:Npn \__fp_parse_word_acotd:N { \__fp_parse_function:NNN \__fp_acot_o:Nw \use_ii:nn } \cs_new_nopar:Npn \__fp_parse_word_atan:N { \__fp_parse_function:NNN \__fp_atan_o:Nw \use_i:nn } \cs_new_nopar:Npn \__fp_parse_word_atand:N { \__fp_parse_function:NNN \__fp_atan_o:Nw \use_ii:nn } \cs_new_nopar:Npn \__fp_parse_word_max:N { \__fp_parse_function:NNN \__fp_minmax_o:Nw 2 } \cs_new_nopar:Npn \__fp_parse_word_min:N { \__fp_parse_function:NNN \__fp_minmax_o:Nw 0 } \cs_new:Npn \__fp_parse_word_abs:N { \__fp_parse_unary_function:nNN { set_sign } 0 } \cs_new_nopar:Npn \__fp_parse_word_exp:N { \__fp_parse_unary_function:nNN {exp} ? } \cs_new_nopar:Npn \__fp_parse_word_ln:N { \__fp_parse_unary_function:nNN {ln} ? } \cs_new_nopar:Npn \__fp_parse_word_sqrt:N { \__fp_parse_unary_function:nNN {sqrt} ? } \tl_map_inline:nn { {acos} {acsc} {asec} {asin} {cos} {cot} {csc} {sec} {sin} {tan} } { \cs_new_nopar:cpn { __fp_parse_word_#1:N } { \__fp_parse_unary_function:nNN {#1} \use_i:nn } \cs_new_nopar:cpn { __fp_parse_word_#1d:N } { \__fp_parse_unary_function:nNN {#1} \use_ii:nn } } \cs_new_nopar:Npn \__fp_parse_word_trunc:N { \__fp_parse_function:NNN \__fp_round_o:Nw \__fp_round_to_zero:NNN } \cs_new_nopar:Npn \__fp_parse_word_floor:N { \__fp_parse_function:NNN \__fp_round_o:Nw \__fp_round_to_ninf:NNN } \cs_new_nopar:Npn \__fp_parse_word_ceil:N { \__fp_parse_function:NNN \__fp_round_o:Nw \__fp_round_to_pinf:NNN } \cs_new:Npn \__fp_parse_word_round:N #1#2 { \if_meaning:w + #2 \__fp_parse_round:Nw \__fp_round_to_pinf:NNN \else: \if_meaning:w 0 #2 \__fp_parse_round:Nw \__fp_round_to_zero:NNN \else: \if_meaning:w - #2 \__fp_parse_round:Nw \__fp_round_to_ninf:NNN \fi: \fi: \fi: \__fp_parse_function:NNN \__fp_round_o:Nw \__fp_round_to_nearest:NNN #1 #2 } \cs_new:Npn \__fp_parse_round:Nw #1 #2 \__fp_round_to_nearest:NNN #3#4 { #2 #1 #3 } \cs_new:Npn \__fp_parse:n #1 { \tex_romannumeral:D \exp_after:wN \__fp_parse_after:ww \tex_romannumeral:D \__fp_parse_operand:Nw \c_minus_one \__fp_parse_expand:w #1 \s__fp_mark \s__fp_stop } \cs_new:Npn \__fp_parse_after:ww #1@ \__fp_parse_infix_end:N \s__fp_mark \s__fp_stop { \c_zero #1 } \cs_new:Npn \__fp_parse_operand:Nw #1 { -`0 \exp_after:wN \__fp_parse_continue:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \exp_after:wN \__fp_parse_one:Nw \exp_after:wN #1 \tex_romannumeral:D } \cs_new:Npn \__fp_parse_continue:NwN #1 #2 @ #3 { #3 #1 #2 @ } \cs_new:Npn \__fp_parse_apply_binary:NwNwN #1 #2@ #3 #4@ #5 { \exp_after:wN \__fp_parse_continue:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \cs:w __fp_#3_o:ww \cs_end: #2 #4 \tex_romannumeral:D -`0 #5 #1 } \cs_new:Npn \__fp_parse_infix_after_operand:NwN #1 #2; { \__fp_exp_after_f:nw { \__fp_parse_infix:NN #1 } #2; } \group_begin: \char_set_catcode_letter:N \* \cs_new:Npn \__fp_parse_infix:NN #1 #2 { \if_catcode:w \scan_stop: \exp_not:N #2 \if_int_compare:w \pdftex_strcmp:D { \s__fp_mark } { \exp_not:N #2 } = \c_zero \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_infix_end:N \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_infix_juxtapose:N \fi: \else: \if_int_compare:w \__int_eval:w ( `#2 \if_int_compare:w `#2 > `Z - \c_thirty_two \fi: ) / 26 = \c_three \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_infix_juxtapose:N \else: \exp_after:wN \__fp_parse_infix_check:NNN \cs:w __fp_parse_infix_#2:N \exp_after:wN \exp_after:wN \exp_after:wN \cs_end: \fi: \fi: #1 #2 } \cs_new:Npn \__fp_parse_infix_check:NNN #1#2#3 { \if_meaning:w \scan_stop: #1 \__msg_kernel_expandable_error:nnn { kernel } { fp-missing } { * } \exp_after:wN \__fp_parse_infix_*:N \exp_after:wN #2 \exp_after:wN #3 \else: \exp_after:wN #1 \exp_after:wN #2 \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \fi: } \group_end: \cs_new:Npn \__fp_parse_infix_end:N #1 { @ \use_none:n \__fp_parse_infix_end:N } \group_begin: \char_set_catcode_letter:N \) \cs_new:Npn \__fp_parse_infix_):N #1 { \if_int_compare:w #1 < \c_zero \__msg_kernel_expandable_error:nnn { kernel } { fp-extra } { ) } \exp_after:wN \__fp_parse_infix:NN \exp_after:wN #1 \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN \__fp_parse_infix_):N \fi: } \group_end: \group_begin: \char_set_catcode_letter:N \, \cs_new:Npn \__fp_parse_infix_,:N #1 { \if_int_compare:w #1 > \c_one \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN \__fp_parse_infix_,:N \else: \if_int_compare:w #1 = \c_one \exp_after:wN \__fp_parse_infix_comma:w \tex_romannumeral:D \else: \exp_after:wN \__fp_parse_infix_comma_gobble:w \tex_romannumeral:D \fi: \__fp_parse_operand:Nw \c_one \exp_after:wN \__fp_parse_expand:w \fi: } \cs_new:Npn \__fp_parse_infix_comma:w #1 @ { #1 @ \use_none:n } \cs_new:Npn \__fp_parse_infix_comma_gobble:w #1 @ { \__msg_kernel_expandable_error:nn { kernel } { fp-extra-comma } @ \use_none:n } \group_end: \group_begin: \char_set_catcode_other:N \& \char_set_catcode_letter:N \^ \char_set_catcode_letter:N \/ \char_set_catcode_letter:N \- \char_set_catcode_letter:N \+ \cs_set_protected:Npn \__fp_tmp:w #1#2#3#4 { \cs_new:Npn #1 ##1 { \if_int_compare:w ##1 < #3 \exp_after:wN @ \exp_after:wN \__fp_parse_apply_binary:NwNwN \exp_after:wN #2 \tex_romannumeral:D \__fp_parse_operand:Nw #4 \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN #1 \fi: } } \__fp_tmp:w \__fp_parse_infix_^:N ^ \c_fifteen \c_fourteen \__fp_tmp:w \__fp_parse_infix_/:N / \c_ten \c_ten \__fp_tmp:w \__fp_parse_infix_mul:N * \c_ten \c_ten \__fp_tmp:w \__fp_parse_infix_-:N - \c_nine \c_nine \__fp_tmp:w \__fp_parse_infix_+:N + \c_nine \c_nine \__fp_tmp:w \__fp_parse_infix_and:N & \c_five \c_five \__fp_tmp:w \__fp_parse_infix_or:N | \c_four \c_four \group_end: \cs_new:cpn { __fp_parse_infix_(:N } #1 { \__fp_parse_infix_juxtapose:N #1 ( } \cs_new:Npn \__fp_parse_infix_juxtapose:N #1 { \if_int_compare:w #1 < \c_thirty_two \exp_after:wN @ \exp_after:wN \__fp_parse_apply_juxtapose:NwwN \tex_romannumeral:D \__fp_parse_operand:Nw \c_thirty_two \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN \__fp_parse_infix_juxtapose:N \fi: } \cs_new:Npn \__fp_parse_apply_juxtapose:NwwN #1 #2;#3@ #4;#5@ { \if_catcode:w ^ \tl_to_str:n { #3 #5 } ^ \else: \__fp_error:nffn { invalid-ii } { \__fp_array_to_clist:n { #2; #3 } } { \__fp_array_to_clist:n { #4; #5 } } { } \fi: \__fp_parse_apply_binary:NwNwN #1 #2;@ * #4;@ } \group_begin: \char_set_catcode_letter:N ^ \cs_new:cpn { __fp_parse_infix_*:N } #1#2 { \if:w * \exp_not:N #2 \exp_after:wN \__fp_parse_infix_^:N \exp_after:wN #1 \else: \exp_after:wN \__fp_parse_infix_mul:N \exp_after:wN #1 \exp_after:wN #2 \fi: } \group_end: \group_begin: \char_set_catcode_letter:N \| \char_set_catcode_letter:N \& \cs_new:Npn \__fp_parse_infix_|:N #1#2 { \if:w | \exp_not:N #2 \exp_after:wN \__fp_parse_infix_|:N \exp_after:wN #1 \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN \__fp_parse_infix_or:N \exp_after:wN #1 \exp_after:wN #2 \fi: } \cs_new:Npn \__fp_parse_infix_&:N #1#2 { \if:w & \exp_not:N #2 \exp_after:wN \__fp_parse_infix_&:N \exp_after:wN #1 \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN \__fp_parse_infix_and:N \exp_after:wN #1 \exp_after:wN #2 \fi: } \group_end: \group_begin: \char_set_catcode_letter:N \? \cs_new:Npn \__fp_parse_infix_?:N #1 { \if_int_compare:w #1 < \c_three \exp_after:wN @ \exp_after:wN \__fp_ternary:NwwN \tex_romannumeral:D \__fp_parse_operand:Nw \c_three \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN \__fp_parse_infix_?:N \fi: } \cs_new:Npn \__fp_parse_infix_::N #1 { \if_int_compare:w #1 < \c_three \__msg_kernel_expandable_error:nnnn { kernel } { fp-missing } { ? } { ~for~?: } \exp_after:wN @ \exp_after:wN \__fp_ternary_auxii:NwwN \tex_romannumeral:D \__fp_parse_operand:Nw \c_two \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN \__fp_parse_infix_::N \fi: } \group_end: \cs_new:cpn { __fp_parse_infix_<:N } #1 { \__fp_parse_compare:NNNNNNN #1 \c_one \c_zero \c_zero \c_zero \c_zero < } \cs_new:cpn { __fp_parse_infix_=:N } #1 { \__fp_parse_compare:NNNNNNN #1 \c_one \c_zero \c_zero \c_zero \c_zero = } \cs_new:cpn { __fp_parse_infix_>:N } #1 { \__fp_parse_compare:NNNNNNN #1 \c_one \c_zero \c_zero \c_zero \c_zero > } \cs_new:cpn { __fp_parse_infix_!:N } #1 { \exp_after:wN \__fp_parse_compare:NNNNNNN \exp_after:wN #1 \exp_after:wN \c_zero \exp_after:wN \c_one \exp_after:wN \c_one \exp_after:wN \c_one \exp_after:wN \c_one } \cs_new:Npn \__fp_parse_excl_error: { \__msg_kernel_expandable_error:nnnn { kernel } { fp-missing } { = } { ~after~!. } } \cs_new:Npn \__fp_parse_compare:NNNNNNN #1 { \if_int_compare:w #1 < \c_seven \exp_after:wN \__fp_parse_compare_auxi:NNNNNNN \exp_after:wN \__fp_parse_excl_error: \else: \exp_after:wN @ \exp_after:wN \use_none:n \exp_after:wN \__fp_parse_compare:NNNNNNN \fi: } \cs_new:Npn \__fp_parse_compare_auxi:NNNNNNN #1#2#3#4#5#6#7 { \if_case:w \if_catcode:w \scan_stop: \exp_not:N #7 \c_minus_one \else: \__int_eval:w `#7 - `< \__int_eval_end: \fi: \__fp_parse_compare_auxii:NNNNN #2#2#4#5#6 \or: \__fp_parse_compare_auxii:NNNNN #2#3#2#5#6 \or: \__fp_parse_compare_auxii:NNNNN #2#3#4#2#6 \or: \__fp_parse_compare_auxii:NNNNN #2#3#4#5#2 \else: #1 \__fp_parse_compare_end:NNNNw #3#4#5#6#7 \fi: } \cs_new:Npn \__fp_parse_compare_auxii:NNNNN #1#2#3#4#5 { \exp_after:wN \__fp_parse_compare_auxi:NNNNNNN \exp_after:wN \prg_do_nothing: \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 \exp_after:wN #5 \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_compare_end:NNNNw #1#2#3#4#5 \fi: { \fi: \exp_after:wN @ \exp_after:wN \__fp_parse_apply_compare:NwNNNNNwN \exp_after:wN \c_one_fp \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 \tex_romannumeral:D \__fp_parse_operand:Nw \c_seven \__fp_parse_expand:w #5 } \cs_new:Npn \__fp_parse_apply_compare:NwNNNNNwN #1 #2@ #3 #4#5#6#7 #8@ #9 { \if_int_odd:w \if_meaning:w \c_zero_fp #3 \c_zero \else: \if_case:w \__fp_compare_back:ww #8 #2 \exp_stop_f: #5 \or: #6 \or: #7 \else: #4 \fi: \fi: \exp_after:wN \__fp_parse_apply_compare_aux:NNwN \exp_after:wN \c_one_fp \else: \exp_after:wN \__fp_parse_apply_compare_aux:NNwN \exp_after:wN \c_zero_fp \fi: #1 #8 #9 } \cs_new:Npn \__fp_parse_apply_compare_aux:NNwN #1 #2 #3; #4 { \if_meaning:w \__fp_parse_compare:NNNNNNN #4 \exp_after:wN \__fp_parse_continue_compare:NNwNN \exp_after:wN #1 \exp_after:wN #2 \tex_romannumeral:D -`0 \__fp_exp_after_o:w #3; \tex_romannumeral:D -`0 \else: \exp_after:wN \__fp_parse_continue:NwN \exp_after:wN #2 \tex_romannumeral:D -`0 \exp_after:wN #1 \tex_romannumeral:D -`0 \fi: #4 #2 } \cs_new:Npn \__fp_parse_continue_compare:NNwNN #1#2 #3@ #4#5 { #4 #2 #3@ #1 } \group_begin: \char_set_catcode_other:N \^^@ \cs_new:Npn \fp_function:Nw #1 { ^^@ ; { \exp_after:wN #1 } } \group_end: \group_begin: \char_set_catcode_other:N \^^@ \cs_new_protected:Npn \fp_new_function:Npn #1#2# { \cs_new:Npx #1 { ^^@ ; { \exp_not:N \exp_after:wN \exp_not:N \__fp_function_args:Nwn \exp_not:N \exp_after:wN \exp_not:c { __fp_user_ \cs_to_str:N #1 } \exp_not:N \__int_value:w \int_eval:n { \tl_count:n {#2} / \c_two } \exp_not:N \exp_after:wN ; } } \cs_new:cpn { __fp_user_ \cs_to_str:N #1 } #2 } \group_end: \cs_new:Npn \__fp_function_args:Nwn #1#2; #3 { \int_compare:nNnTF { \tl_count:n {#3} } = {#2} { #1 #3 } { \__msg_kernel_expandable_error:nnnnn { kernel } { fp-num-args } { #1() } {#2} {#2} \c_nan_fp } } \group_begin: \char_set_catcode_other:N \^^@ \cs_new:cpn { __fp_parse_prefix_ ^^@ :Nw } #1 ; #2 { \exp_after:wN \__fp_function_apply:NnwN \exp_after:wN #1 \exp_after:wN { #2 \exp_after:wN } \tex_romannumeral:D \__fp_parse_operand:Nw \c_sixteen \__fp_parse_expand:w } \group_end: \cs_new:Npn \__fp_function_apply:NnwN #1#2#3@#4 { \exp_after:wN \__fp_exp_after_array_f:w \tex_romannumeral:D -`0 \__fp_function_store:wwNwnn #3 \s__fp_mark \__fp_function_store:wwNwnn ; \s__fp_mark \__fp_function_store_end:wnnn \s__fp_stop { } { } {#2} \s__fp_stop #4 #1 } \cs_new:Npn \__fp_function_store:wwNwnn #1; #2 \s__fp_mark #3#4 \s__fp_stop #5#6 { #3 #2 \s__fp_mark #3#4 \s__fp_stop { #5 #6 } { { #1; } } } \cs_new:Npn \__fp_function_store_end:wnnn #1 \s__fp_stop #2#3#4 { \__fp_parse:n { #4 {#2} } } \__msg_kernel_new:nnn { kernel } { unknown-fp-word } { Unknown~fp~word~#1. } \__msg_kernel_new:nnn { kernel } { fp-missing } { Missing~#1~inserted #2. } \__msg_kernel_new:nnn { kernel } { fp-extra } { Extra~#1~ignored. } \__msg_kernel_new:nnn { kernel } { fp-early-end } { Premature~end~in~fp~expression. } \__msg_kernel_new:nnn { kernel } { fp-after-e } { Cannot~use~#1 after~'e'. } \__msg_kernel_new:nnn { kernel } { fp-missing-number } { Missing~number~before~'#1'. } \__msg_kernel_new:nnn { kernel } { fp-unknown-symbol } { Unknown~symbol~#1~ignored. } \__msg_kernel_new:nnn { kernel } { fp-extra-comma } { Unexpected~comma:~extra~arguments~ignored. } \__msg_kernel_new:nnn { kernel } { fp-num-args } { #1~expects~between~#2~and~#3~arguments. } %% File: l3fp-logic.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \prg_new_eq_conditional:NNn \fp_if_exist:N \cs_if_exist:N { TF , T , F , p } \prg_new_eq_conditional:NNn \fp_if_exist:c \cs_if_exist:c { TF , T , F , p } \prg_new_conditional:Npnn \fp_compare:n #1 { p , T , F , TF } { \exp_after:wN \__fp_compare_return:w \tex_romannumeral:D -`0 \__fp_parse:n {#1} } \cs_new:Npn \__fp_compare_return:w \s__fp \__fp_chk:w #1#2; { \if_meaning:w 0 #1 \prg_return_false: \else: \prg_return_true: \fi: } \prg_new_conditional:Npnn \fp_compare:nNn #1#2#3 { p , T , F , TF } { \if_int_compare:w \exp_after:wN \__fp_compare_aux:wn \tex_romannumeral:D -`0 \__fp_parse:n {#1} {#3} = \__int_eval:w `#2 - `= \__int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } \cs_new:Npn \__fp_compare_aux:wn #1; #2 { \exp_after:wN \__fp_compare_back:ww \tex_romannumeral:D -`0 \__fp_parse:n {#2} #1; } \cs_new:Npn \__fp_compare_back:ww \s__fp \__fp_chk:w #1 #2 #3; \s__fp \__fp_chk:w #4 #5 #6; { \__int_value:w \if_meaning:w 3 #1 \exp_after:wN \__fp_compare_nan:w \fi: \if_meaning:w 3 #4 \exp_after:wN \__fp_compare_nan:w \fi: \if_meaning:w 2 #5 - \fi: \if_meaning:w #2 #5 \if_meaning:w #1 #4 \if_meaning:w 1 #1 \__fp_compare_npos:nwnw #6; #3; \else: 0 \fi: \else: \if_int_compare:w #4 < #1 - \fi: 1 \fi: \else: \if_int_compare:w #1#4 = \c_zero 0 \else: 1 \fi: \fi: \exp_stop_f: } \cs_new:Npn \__fp_compare_nan:w #1 \exp_stop_f: { \c_two } \cs_new:Npn \__fp_compare_npos:nwnw #1#2; #3#4; { \if_int_compare:w #1 = #3 \exp_stop_f: \__fp_compare_significand:nnnnnnnn #2 #4 \else: \if_int_compare:w #1 < #3 - \fi: 1 \fi: } \cs_new:Npn \__fp_compare_significand:nnnnnnnn #1#2#3#4#5#6#7#8 { \if_int_compare:w #1#2 = #5#6 \exp_stop_f: \if_int_compare:w #3#4 = #7#8 \exp_stop_f: 0 \else: \if_int_compare:w #3#4 < #7#8 - \fi: 1 \fi: \else: \if_int_compare:w #1#2 < #5#6 - \fi: 1 \fi: } \cs_new:Npn \fp_do_until:nn #1#2 { #2 \fp_compare:nF {#1} { \fp_do_until:nn {#1} {#2} } } \cs_new:Npn \fp_do_while:nn #1#2 { #2 \fp_compare:nT {#1} { \fp_do_while:nn {#1} {#2} } } \cs_new:Npn \fp_until_do:nn #1#2 { \fp_compare:nF {#1} { #2 \fp_until_do:nn {#1} {#2} } } \cs_new:Npn \fp_while_do:nn #1#2 { \fp_compare:nT {#1} { #2 \fp_while_do:nn {#1} {#2} } } \cs_new:Npn \fp_do_until:nNnn #1#2#3#4 { #4 \fp_compare:nNnF {#1} #2 {#3} { \fp_do_until:nNnn {#1} #2 {#3} {#4} } } \cs_new:Npn \fp_do_while:nNnn #1#2#3#4 { #4 \fp_compare:nNnT {#1} #2 {#3} { \fp_do_while:nNnn {#1} #2 {#3} {#4} } } \cs_new:Npn \fp_until_do:nNnn #1#2#3#4 { \fp_compare:nNnF {#1} #2 {#3} { #4 \fp_until_do:nNnn {#1} #2 {#3} {#4} } } \cs_new:Npn \fp_while_do:nNnn #1#2#3#4 { \fp_compare:nNnT {#1} #2 {#3} { #4 \fp_while_do:nNnn {#1} #2 {#3} {#4} } } \cs_new:Npn \__fp_minmax_o:Nw #1#2 @ { \if_meaning:w 0 #1 \exp_after:wN \__fp_minmax_loop:Nww \exp_after:wN \c_one \else: \exp_after:wN \__fp_minmax_loop:Nww \exp_after:wN \c_minus_one \fi: #2 \s__fp \__fp_chk:w 2 #1 \s__fp_exact ; \s__fp \__fp_chk:w { 3 \__fp_minmax_break_o:w } ; } \cs_new:Npn \__fp_minmax_loop:Nww #1 \s__fp \__fp_chk:w #2#3; \s__fp \__fp_chk:w #4#5; { \if_meaning:w 3 #4 \if_meaning:w 3 #2 \__fp_minmax_auxi:ww \else: \__fp_minmax_auxii:ww \fi: \else: \if_int_compare:w \__fp_compare_back:ww \s__fp \__fp_chk:w #4#5; \s__fp \__fp_chk:w #2#3; = #1 \__fp_minmax_auxii:ww \else: \__fp_minmax_auxi:ww \fi: \fi: \__fp_minmax_loop:Nww #1 \s__fp \__fp_chk:w #2#3; \s__fp \__fp_chk:w #4#5; } \cs_new:Npn \__fp_minmax_auxi:ww #1 \fi: \fi: #2 \s__fp #3 ; \s__fp #4; { \fi: \fi: #2 \s__fp #3 ; } \cs_new:Npn \__fp_minmax_auxii:ww #1 \fi: \fi: #2 \s__fp #3 ; { \fi: \fi: #2 } \cs_new:Npn \__fp_minmax_break_o:w #1 \fi: \fi: #2 \s__fp #3; #4; { \fi: \__fp_exp_after_o:w \s__fp #3; } \cs_new:cpn { __fp_not_o:w } #1 \s__fp \__fp_chk:w #2#3; @ { \if_meaning:w 0 #2 \exp_after:wN \exp_after:wN \exp_after:wN \c_one_fp \else: \exp_after:wN \exp_after:wN \exp_after:wN \c_zero_fp \fi: } \group_begin: \char_set_catcode_letter:N & \char_set_catcode_letter:N | \cs_new:Npn \__fp_&_o:ww #1 \s__fp \__fp_chk:w #2#3; { \if_meaning:w 0 #2 #1 \__fp_and_return:wNw \s__fp \__fp_chk:w #2#3; \fi: \__fp_exp_after_o:w } \cs_new_nopar:Npn \__fp_|_o:ww { \__fp_&_o:ww \else: } \group_end: \cs_new:Npn \__fp_and_return:wNw #1; \fi: #2#3; { \fi: #2 #1; } \cs_new:Npn \__fp_ternary:NwwN #1 #2@ #3@ #4 { \if_meaning:w \__fp_parse_infix_::N #4 \__fp_ternary_loop:Nw #2 \s__fp \__fp_chk:w { \__fp_ternary_loop_break:w } ; \__fp_ternary_break_point:n { \exp_after:wN \__fp_ternary_auxi:NwwN } \exp_after:wN #1 \tex_romannumeral:D -`0 \__fp_exp_after_array_f:w #3 \s__fp_stop \exp_after:wN @ \tex_romannumeral:D \__fp_parse_operand:Nw \c_two \__fp_parse_expand:w \else: \__msg_kernel_expandable_error:nnnn { kernel } { fp-missing } { : } { ~for~?: } \exp_after:wN \__fp_parse_continue:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \__fp_exp_after_array_f:w #3 \s__fp_stop \exp_after:wN #4 \exp_after:wN #1 \fi: } \cs_new:Npn \__fp_ternary_loop_break:w #1 \fi: #2 \__fp_ternary_break_point:n #3 { \c_zero = \c_zero \fi: \exp_after:wN \__fp_ternary_auxii:NwwN } \cs_new:Npn \__fp_ternary_loop:Nw \s__fp \__fp_chk:w #1#2; { \if_int_compare:w #1 > \c_zero \exp_after:wN \__fp_ternary_map_break: \fi: \__fp_ternary_loop:Nw } \cs_new:Npn \__fp_ternary_map_break: #1 \__fp_ternary_break_point:n #2 {#2} \cs_new:Npn \__fp_ternary_auxi:NwwN #1#2@#3@#4 { \exp_after:wN \__fp_parse_continue:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \__fp_exp_after_array_f:w #2 \s__fp_stop #4 #1 } \cs_new:Npn \__fp_ternary_auxii:NwwN #1#2@#3@#4 { \exp_after:wN \__fp_parse_continue:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \__fp_exp_after_array_f:w #3 \s__fp_stop #4 #1 } %% File: l3fp-basics.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new:Npn \__fp_basics_pack_low:NNNNNw #1 #2#3#4#5 #6; { + #1 - \c_one ; {#2#3#4#5} {#6} ; } \cs_new:Npn \__fp_basics_pack_high:NNNNNw #1 #2#3#4#5 #6; { \if_meaning:w 2 #1 \__fp_basics_pack_high_carry:w \fi: ; {#2#3#4#5} {#6} } \cs_new:Npn \__fp_basics_pack_high_carry:w \fi: ; #1 { \fi: + \c_one ; {1000} } \cs_new:Npn \__fp_basics_pack_weird_low:NNNNw #1 #2#3#4 #5; { \if_meaning:w 2 #1 + \c_one \fi: \__int_eval_end: #2#3#4; {#5} ; } \cs_new:Npn \__fp_basics_pack_weird_high:NNNNNNNNw 1 #1#2#3#4 #5#6#7#8 #9; { ; {#1#2#3#4} {#5#6#7#8} {#9} } \cs_new_nopar:cpx { __fp_-_o:ww } \s__fp { \exp_not:c { __fp_+_o:ww } \exp_not:n { \s__fp \__fp_neg_sign:N } } \cs_new:cpn { __fp_+_o:ww } \s__fp #1 \__fp_chk:w #2 #3 ; \s__fp \__fp_chk:w #4 #5 { \if_case:w \if_meaning:w #2 #4 #2 \exp_stop_f: \else: \if_int_compare:w #2 > #4 \exp_stop_f: \c_three \else: \c_minus_one \fi: \fi: \exp_after:wN \__fp_add_zeros_o:Nww \__int_value:w \or: \exp_after:wN \__fp_add_normal_o:Nww \__int_value:w \or: \exp_after:wN \__fp_add_inf_o:Nww \__int_value:w \or: \__fp_case_return_i_o:ww \else: \exp_after:wN \__fp_add_return_ii_o:Nww \__int_value:w \fi: #1 #5 \s__fp \__fp_chk:w #2 #3 ; \s__fp \__fp_chk:w #4 #5 } \cs_new:Npn \__fp_add_return_ii_o:Nww #1 #2 ; \s__fp \__fp_chk:w #3 #4 { \__fp_exp_after_o:w \s__fp \__fp_chk:w #3 #1 } \cs_new:Npn \__fp_add_zeros_o:Nww #1 \s__fp \__fp_chk:w 0 #2 { \if_int_compare:w #2 #1 = 20 \exp_stop_f: \exp_after:wN \__fp_add_return_ii_o:Nww \else: \__fp_case_return_i_o:ww \fi: #1 \s__fp \__fp_chk:w 0 #2 } \cs_new:Npn \__fp_add_inf_o:Nww #1 \s__fp \__fp_chk:w 2 #2 #3; \s__fp \__fp_chk:w 2 #4 { \if_meaning:w #1 #2 \__fp_case_return_i_o:ww \else: \__fp_case_use:nw { \if_meaning:w #1 #4 \exp_after:wN \__fp_invalid_operation_o:Nww \exp_after:wN + \else: \exp_after:wN \__fp_invalid_operation_o:Nww \exp_after:wN - \fi: } \fi: \s__fp \__fp_chk:w 2 #2 #3; \s__fp \__fp_chk:w 2 #4 } \cs_new:Npn \__fp_add_normal_o:Nww #1 \s__fp \__fp_chk:w 1 #2 { \if_meaning:w #1#2 \exp_after:wN \__fp_add_npos_o:NnwNnw \else: \exp_after:wN \__fp_sub_npos_o:NnwNnw \fi: #2 } \cs_new:Npn \__fp_add_npos_o:NnwNnw #1#2#3 ; \s__fp \__fp_chk:w 1 #4 #5 { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w \if_int_compare:w #2 > #5 \exp_stop_f: #2 \exp_after:wN \__fp_add_big_i_o:wNww \__int_value:w - \else: #5 \exp_after:wN \__fp_add_big_ii_o:wNww \__int_value:w \fi: \__int_eval:w #5 - #2 ; #1 #3; } \cs_new:Npn \__fp_add_big_i_o:wNww #1; #2 #3; #4; { \__fp_decimate:nNnnnn {#1} \__fp_add_significand_o:NnnwnnnnN #4 #3 #2 } \cs_new:Npn \__fp_add_big_ii_o:wNww #1; #2 #3; #4; { \__fp_decimate:nNnnnn {#1} \__fp_add_significand_o:NnnwnnnnN #3 #4 #2 } \cs_new:Npn \__fp_add_significand_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 { \exp_after:wN \__fp_add_significand_test_o:N \int_use:N \__int_eval:w 1#5#6 + #2 \exp_after:wN \__fp_add_significand_pack:NNNNNNN \int_use:N \__int_eval:w 1#7#8 + #3 ; #1 } \cs_new:Npn \__fp_add_significand_pack:NNNNNNN #1 #2#3#4#5#6#7 { \if_meaning:w 2 #1 + \c_one \fi: ; #2 #3 #4 #5 #6 #7 ; } \cs_new:Npn \__fp_add_significand_test_o:N #1 { \if_meaning:w 2 #1 \exp_after:wN \__fp_add_significand_carry_o:wwwNN \else: \exp_after:wN \__fp_add_significand_no_carry_o:wwwNN \fi: } \cs_new:Npn \__fp_add_significand_no_carry_o:wwwNN #1; #2; #3#4 ; #5#6 { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1 #1 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 1 #2 #3#4 + \__fp_round:NNN #6 #4 #5 \exp_after:wN ; } \cs_new:Npn \__fp_add_significand_carry_o:wwwNN #1; #2; #3#4; #5#6 { + \c_one \exp_after:wN \__fp_basics_pack_weird_high:NNNNNNNNw \int_use:N \__int_eval:w 1 1 #1 \exp_after:wN \__fp_basics_pack_weird_low:NNNNw \int_use:N \__int_eval:w 1 #2#3 + \exp_after:wN \__fp_round:NNN \exp_after:wN #6 \exp_after:wN #3 \__int_value:w \__fp_round_digit:Nw #4 #5 ; \exp_after:wN ; } \cs_new:Npn \__fp_sub_npos_o:NnwNnw #1#2#3; \s__fp \__fp_chk:w 1 #4#5#6; { \if_case:w \__fp_compare_npos:nwnw {#2} #3; {#5} #6; \exp_stop_f: \exp_after:wN \__fp_sub_eq_o:Nnwnw \or: \exp_after:wN \__fp_sub_npos_i_o:Nnwnw \else: \exp_after:wN \__fp_sub_npos_ii_o:Nnwnw \fi: #1 {#2} #3; {#5} #6; } \cs_new:Npn \__fp_sub_eq_o:Nnwnw #1#2; #3; { \exp_after:wN \c_zero_fp } \cs_new:Npn \__fp_sub_npos_ii_o:Nnwnw #1 #2; #3; { \exp_after:wN \__fp_sub_npos_i_o:Nnwnw \int_use:N \__int_eval:w \c_two - #1 \__int_eval_end: #3; #2; } \cs_new:Npn \__fp_sub_npos_i_o:Nnwnw #1 #2#3; #4#5; { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w #2 \if_int_compare:w #2 = #4 \exp_stop_f: \exp_after:wN \__fp_sub_back_near_o:nnnnnnnnN \else: \exp_after:wN \__fp_decimate:nNnnnn \exp_after:wN { \int_use:N \__int_eval:w #2 - #4 - \c_one \exp_after:wN } \exp_after:wN \__fp_sub_back_far_o:NnnwnnnnN \fi: #5 #3 #1 } \cs_new:Npn \__fp_sub_back_near_o:nnnnnnnnN #1#2#3#4 #5#6#7#8 #9 { \exp_after:wN \__fp_sub_back_near_after:wNNNNw \int_use:N \__int_eval:w 10#5#6 - #1#2 - \c_eleven \exp_after:wN \__fp_sub_back_near_pack:NNNNNNw \int_use:N \__int_eval:w 11#7#8 - #3#4 \exp_after:wN ; } \cs_new:Npn \__fp_sub_back_near_pack:NNNNNNw #1#2#3#4#5#6#7 ; { + #1#2 ; {#3#4#5#6} {#7} ; } \cs_new:Npn \__fp_sub_back_near_after:wNNNNw 10 #1#2#3#4 #5 ; { \if_meaning:w 0 #1 \exp_after:wN \__fp_sub_back_shift:wnnnn \fi: ; {#1#2#3#4} {#5} } \cs_new:Npn \__fp_sub_back_shift:wnnnn ; #1#2 { \exp_after:wN \__fp_sub_back_shift_ii:ww \__int_value:w #1 #2 0 ; } \cs_new:Npn \__fp_sub_back_shift_ii:ww #1 0 ; #2#3 ; { \if_meaning:w @ #1 @ - \c_seven - \exp_after:wN \use_i:nnn \exp_after:wN \__fp_sub_back_shift_iii:NNNNNNNNw \__int_value:w #2#3 0 ~ 123456789; \else: - \__fp_sub_back_shift_iii:NNNNNNNNw #1 123456789; \fi: \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_sub_back_shift_iv:nnnnw \exp_after:wN ; \__int_value:w #1 ~ #2#3 0 ~ 0000 0000 0000 000 ; } \cs_new:Npn \__fp_sub_back_shift_iii:NNNNNNNNw #1#2#3#4#5#6#7#8#9; {#8} \cs_new:Npn \__fp_sub_back_shift_iv:nnnnw #1 ; #2 ; { ; #1 ; } \cs_new:Npn \__fp_sub_back_far_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 { \if_case:w \if_int_compare:w 1 #2 = #5#6 \use_i:nnnn #7 \exp_stop_f: \if_int_compare:w #3 = \use_none:n #7#8 0 \exp_stop_f: \c_zero \else: \if_int_compare:w #3 > \use_none:n #7#8 0 - \fi: \c_one \fi: \else: \if_int_compare:w 1 #2 > #5#6 \use_i:nnnn #7 - \fi: \c_one \fi: \exp_after:wN \__fp_sub_back_quite_far_o:wwNN \or: \exp_after:wN \__fp_sub_back_very_far_o:wwwwNN \else: \exp_after:wN \__fp_sub_back_not_far_o:wwwwNN \fi: #2 ~ #3 ; #5 #6 ~ #7 #8 ; #1 } \cs_new:Npn \__fp_sub_back_quite_far_o:wwNN #1; #2; #3#4 { \exp_after:wN \__fp_sub_back_quite_far_ii:NN \exp_after:wN #3 \exp_after:wN #4 } \cs_new:Npn \__fp_sub_back_quite_far_ii:NN #1#2 { \if_case:w \__fp_round_neg:NNN #2 0 #1 \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: { ; {1000} {0000} {0000} {0000} ; } { - \c_one ; {9999} {9999} {9999} {9999} ; } } \cs_new:Npn \__fp_sub_back_not_far_o:wwwwNN #1 ~ #2; #3 ~ #4; #5#6 { - \c_one \exp_after:wN \__fp_sub_back_near_after:wNNNNw \int_use:N \__int_eval:w 1#30 - #1 - \c_eleven \exp_after:wN \__fp_sub_back_near_pack:NNNNNNw \int_use:N \__int_eval:w 11 0000 0000 + #40 - #2 - \exp_after:wN \__fp_round_neg:NNN \exp_after:wN #6 \use_none:nnnnnnn #2 #5 \exp_after:wN ; } \cs_new:Npn \__fp_sub_back_very_far_o:wwwwNN #1#2#3#4#5#6#7 { \__fp_pack_eight:wNNNNNNNN \__fp_sub_back_very_far_ii_o:nnNwwNN { 0 #1#2#3 #4#5#6#7 } ; } \cs_new:Npn \__fp_sub_back_very_far_ii_o:nnNwwNN #1#2 ; #3 ; #4 ~ #5; #6#7 { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1#4 - #1 - \c_one \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 2#5 - #2 - \exp_after:wN \__fp_round_neg:NNN \exp_after:wN #7 \__int_value:w \if_int_odd:w \__int_eval:w #5 - #2 \__int_eval_end: 1 \else: 2 \fi: \__int_value:w \__fp_round_digit:Nw #3 #6 ; \exp_after:wN ; } \cs_new_nopar:cpn { __fp_*_o:ww } { \__fp_mul_cases_o:NnNnww * { - \c_two + } \__fp_mul_npos_o:Nww { } } \cs_new:Npn \__fp_mul_cases_o:NnNnww #1#2#3#4 \s__fp \__fp_chk:w #5#6#7; \s__fp \__fp_chk:w #8#9 { \if_case:w \__int_eval:w \if_int_compare:w #5 #8 = \c_eleven \c_one \else: \if_meaning:w 3 #8 \c_three \else: \if_meaning:w 3 #5 \c_two \else: \if_int_compare:w #5 #8 = \c_ten \c_nine #2 - \c_two \else: (#5 #2 #8) / \c_two * \c_two + \c_seven \fi: \fi: \fi: \fi: \if_meaning:w #6 #9 - \c_one \fi: \__int_eval_end: \__fp_case_use:nw { #3 0 } \or: \__fp_case_use:nw { #3 2 } \or: \__fp_case_return_i_o:ww \or: \__fp_case_return_ii_o:ww \or: \__fp_case_return_o:Nww \c_zero_fp \or: \__fp_case_return_o:Nww \c_minus_zero_fp \or: \__fp_case_use:nw { \__fp_invalid_operation_o:Nww #1 } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:Nww #1 } \or: \__fp_case_return_o:Nww \c_inf_fp \or: \__fp_case_return_o:Nww \c_minus_inf_fp #4 \fi: \s__fp \__fp_chk:w #5 #6 #7; \s__fp \__fp_chk:w #8 #9 } \cs_new:Npn \__fp_mul_npos_o:Nww #1 \s__fp \__fp_chk:w #2 #3 #4 #5 ; \s__fp \__fp_chk:w #6 #7 #8 #9 ; { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w #4 + #8 \__fp_mul_significand_o:nnnnNnnnn #5 #1 #9 } \cs_new:Npn \__fp_mul_significand_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9 { \exp_after:wN \__fp_mul_significand_test_f:NNN \exp_after:wN #5 \int_use:N \__int_eval:w 99990000 + #1*#6 + \exp_after:wN \__fp_mul_significand_keep:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#7 + #2*#6 + \exp_after:wN \__fp_mul_significand_keep:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#8 + #2*#7 + #3*#6 + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#9 + #2*#8 + #3*#7 + #4*#6 + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #2*#9 + #3*#8 + #4*#7 + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #3*#9 + #4*#8 + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 100000000 + #4*#9 ; ; \exp_after:wN ; } \cs_new:Npn \__fp_mul_significand_drop:NNNNNw #1#2#3#4#5 #6; { #1#2#3#4#5 ; + #6 } \cs_new:Npn \__fp_mul_significand_keep:NNNNNw #1#2#3#4#5 #6; { #1#2#3#4#5 ; #6 ; } \cs_new:Npn \__fp_mul_significand_test_f:NNN #1 #2 #3 { \if_meaning:w 0 #3 \exp_after:wN \__fp_mul_significand_small_f:NNwwwN \else: \exp_after:wN \__fp_mul_significand_large_f:NwwNNNN \fi: #1 #3 } \cs_new:Npn \__fp_mul_significand_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; + { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1#2 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 1#3#4#5#6#7 + \exp_after:wN \__fp_round:NNN \exp_after:wN #1 \exp_after:wN #7 \__int_value:w \__fp_round_digit:Nw } \cs_new:Npn \__fp_mul_significand_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7 { - \c_one \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1#3#4 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 1#5#6#7 + \exp_after:wN \__fp_round:NNN \exp_after:wN #1 \exp_after:wN #7 \__int_value:w \__fp_round_digit:Nw } \cs_new_nopar:cpn { __fp_/_o:ww } { \__fp_mul_cases_o:NnNnww / { - } \__fp_div_npos_o:Nww { \or: \__fp_case_use:nw { \__fp_division_by_zero_o:NNww \c_inf_fp / } \or: \__fp_case_use:nw { \__fp_division_by_zero_o:NNww \c_minus_inf_fp / } } } \cs_new:Npn \__fp_div_npos_o:Nww #1 \s__fp \__fp_chk:w 1 #2 #3 #4 ; \s__fp \__fp_chk:w 1 #5 #6 #7#8#9; { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w #3 - #6 \exp_after:wN \__fp_div_significand_i_o:wnnw \int_use:N \__int_eval:w #7 \use_i:nnnn #8 + \c_one ; #4 {#7}{#8}#9 ; #1 } \cs_new:Npn \__fp_div_significand_i_o:wnnw #1 ; #2#3 #4 ; { \exp_after:wN \__fp_div_significand_test_o:w \int_use:N \__int_eval:w \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; #4 { \exp_after:wN \__fp_div_significand_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_div_significand_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_div_significand_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_div_significand_iii:wwnnnnn \__int_value:w #1 } } \cs_new:Npn \__fp_div_significand_calc:wwnnnnnnn 1#1 { \if_meaning:w 1 #1 \exp_after:wN \__fp_div_significand_calc_i:wwnnnnnnn \else: \exp_after:wN \__fp_div_significand_calc_ii:wwnnnnnnn \fi: } \cs_new:Npn \__fp_div_significand_calc_i:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 { 1 1 #1 #9 \exp_after:wN ; \int_use:N \__int_eval:w \c__fp_Bigg_leading_shift_int + #2 - #1 * #5 - #5#60 \exp_after:wN \__fp_pack_Bigg:NNNNNNw \int_use:N \__int_eval:w \c__fp_Bigg_middle_shift_int + #3 - #1 * #6 - #70 \exp_after:wN \__fp_pack_Bigg:NNNNNNw \int_use:N \__int_eval:w \c__fp_Bigg_middle_shift_int + #4 - #1 * #7 - #80 \exp_after:wN \__fp_pack_Bigg:NNNNNNw \int_use:N \__int_eval:w \c__fp_Bigg_trailing_shift_int - #1 * #8 ; {#5}{#6}{#7}{#8} } \cs_new:Npn \__fp_div_significand_calc_ii:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 { 1 0 #1 #9 \exp_after:wN ; \int_use:N \__int_eval:w \c__fp_Bigg_leading_shift_int + #2 - #1 * #5 \exp_after:wN \__fp_pack_Bigg:NNNNNNw \int_use:N \__int_eval:w \c__fp_Bigg_middle_shift_int + #3 - #1 * #6 \exp_after:wN \__fp_pack_Bigg:NNNNNNw \int_use:N \__int_eval:w \c__fp_Bigg_middle_shift_int + #4 - #1 * #7 \exp_after:wN \__fp_pack_Bigg:NNNNNNw \int_use:N \__int_eval:w \c__fp_Bigg_trailing_shift_int - #1 * #8 ; {#5}{#6}{#7}{#8} } \cs_new:Npn \__fp_div_significand_ii:wwn #1; #2;#3 { \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; } \cs_new:Npn \__fp_div_significand_iii:wwnnnnn #1; #2;#3#4#5 #6#7 { 0 \exp_after:wN \__fp_div_significand_iv:wwnnnnnnn \int_use:N \__int_eval:w (\c_two * #2 #3) / #6 #7 ; % <- P #2 ; {#3} {#4} {#5} {#6} {#7} } \cs_new:Npn \__fp_div_significand_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9 { + \c_five * #1 \exp_after:wN \__fp_div_significand_vi:Nw \int_use:N \__int_eval:w -20 + 2*#2#3 - #1*#6#7 + \exp_after:wN \__fp_div_significand_v:NN \int_use:N \__int_eval:w 199980 + 2*#4 - #1*#8 + \exp_after:wN \__fp_div_significand_v:NN \int_use:N \__int_eval:w 200000 + 2*#5 - #1*#9 ; } \cs_new:Npn \__fp_div_significand_v:NN #1#2 { #1#2 \__int_eval_end: + } \cs_new:Npn \__fp_div_significand_vi:Nw #1#2; { \if_meaning:w 0 #1 \if_int_compare:w \__int_eval:w #2 > \c_zero + \c_one \fi: \else: \if_meaning:w - #1 - \else: + \fi: \c_one \fi: ; } \cs_new:Npn \__fp_div_significand_pack:NNN 1 #1 #2 { + #1 #2 ; } \cs_new:Npn \__fp_div_significand_test_o:w 10 #1 { \if_meaning:w 0 #1 \exp_after:wN \__fp_div_significand_small_o:wwwNNNNwN \else: \exp_after:wN \__fp_div_significand_large_o:wwwNNNNwN \fi: #1 } \cs_new:Npn \__fp_div_significand_small_o:wwwNNNNwN 0 #1; #2; #3; #4#5#6#7#8; #9 { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1 #1#2 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 1 #3#4#5#6#7 + \__fp_round:NNN #9 #7 #8 \exp_after:wN ; } \cs_new:Npn \__fp_div_significand_large_o:wwwNNNNwN #1; #2; #3; #4#5#6#7#8; #9 { + \c_one \exp_after:wN \__fp_basics_pack_weird_high:NNNNNNNNw \int_use:N \__int_eval:w 1 #1 #2 \exp_after:wN \__fp_basics_pack_weird_low:NNNNw \int_use:N \__int_eval:w 1 #3 #4 #5 #6 + \exp_after:wN \__fp_round:NNN \exp_after:wN #9 \exp_after:wN #6 \__int_value:w \__fp_round_digit:Nw #7 #8 ; \exp_after:wN ; } \cs_new:Npn \__fp_sqrt_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_meaning:w 0 #2 \__fp_case_return_same_o:w \fi: \if_meaning:w 2 #3 \__fp_case_use:nw { \__fp_invalid_operation_o:nw { sqrt } } \fi: \if_meaning:w 1 #2 \else: \__fp_case_return_same_o:w \fi: \__fp_sqrt_npos_o:w \s__fp \__fp_chk:w #2 #3 #4; } \cs_new:Npn \__fp_sqrt_npos_o:w \s__fp \__fp_chk:w 1 0 #1#2#3#4#5; { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN 0 \int_use:N \__int_eval:w \if_int_odd:w #1 \exp_stop_f: \exp_after:wN \__fp_sqrt_npos_auxi_o:wwnnN \fi: #1 / \c_two \__fp_sqrt_Newton_o:wwn 56234133; 0; {#2#3} {#4#5} 0 } \cs_new:Npn \__fp_sqrt_npos_auxi_o:wwnnN #1 / \c_two #2; 0; #3#4#5 { ( #1 + \c_one ) / \c_two \__fp_pack_eight:wNNNNNNNN \__fp_sqrt_npos_auxii_o:wNNNNNNNN ; 0 #3 #4 } \cs_new:Npn \__fp_sqrt_npos_auxii_o:wNNNNNNNN #1; #2#3#4#5#6#7#8#9 { \__fp_sqrt_Newton_o:wwn 17782794; 0; {#1} {#2#3#4#5#6#7#8#9} } \cs_new:Npn \__fp_sqrt_Newton_o:wwn #1; #2; #3 { \if_int_compare:w #1 = #2 \exp_stop_f: \exp_after:wN \__fp_sqrt_auxi_o:NNNNwnnN \int_use:N \__int_eval:w 9999 9999 + \exp_after:wN \__fp_use_none_until_s:w \fi: \exp_after:wN \__fp_sqrt_Newton_o:wwn \int_use:N \__int_eval:w (#1 + #3 * 1 0000 0000 / #1) / \c_two ; #1; {#3} } \cs_new:Npn \__fp_sqrt_auxi_o:NNNNwnnN 1 #1#2#3#4#5; { \__fp_sqrt_auxii_o:NnnnnnnnN \__fp_sqrt_auxiii_o:wnnnnnnnn {#1#2#3#4} {#5} {2499} {9988} {7500} } \cs_new:Npn \__fp_sqrt_auxii_o:NnnnnnnnN #1 #2#3#4#5#6 #7#8#9 { \exp_after:wN #1 \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + #7 - #2 * #2 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - 2 * #2 * #3 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #8 - #3 * #3 - 2 * #2 * #4 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - 2 * #3 * #4 - 2 * #2 * #5 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #9 000 0000 - #4 * #4 - 2 * #3 * #5 - 2 * #2 * #6 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - 2 * #4 * #5 - 2 * #3 * #6 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - #5 * #5 - 2 * #4 * #6 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - 2 * #5 * #6 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_trailing_shift_int - #6 * #6 ; % ( - 257 ) * 5000 0000 / (#2#3 + 1) + 10 0000 0000 ; {#2}{#3}{#4}{#5}{#6} {#7}{#8}#9 } \cs_new:Npn \__fp_sqrt_auxiii_o:wnnnnnnnn #1; #2#3#4#5#6#7#8#9 { \if_int_compare:w #1 > \c_one \exp_after:wN \__fp_sqrt_auxiv_o:NNNNNw \int_use:N \__int_eval:w (#1#2 %) \else: \if_int_compare:w #1#2 > \c_one \exp_after:wN \__fp_sqrt_auxv_o:NNNNNw \int_use:N \__int_eval:w (#1#2#3 %) \else: \if_int_compare:w #1#2#3 > \c_one \exp_after:wN \__fp_sqrt_auxvi_o:NNNNNw \int_use:N \__int_eval:w (#1#2#3#4 %) \else: \exp_after:wN \__fp_sqrt_auxvii_o:NNNNNw \int_use:N \__int_eval:w (#1#2#3#4#5 %) \fi: \fi: \fi: } \cs_new:Npn \__fp_sqrt_auxiv_o:NNNNNw 1#1#2#3#4#5#6; { \__fp_sqrt_auxviii_o:nnnnnnn {#1#2#3#4#5#6} {00000000} } \cs_new:Npn \__fp_sqrt_auxv_o:NNNNNw 1#1#2#3#4#5#6; { \__fp_sqrt_auxviii_o:nnnnnnn {000#1#2#3#4#5} {#60000} } \cs_new:Npn \__fp_sqrt_auxvi_o:NNNNNw 1#1#2#3#4#5#6; { \__fp_sqrt_auxviii_o:nnnnnnn {0000000#1} {#2#3#4#5#6} } \cs_new:Npn \__fp_sqrt_auxvii_o:NNNNNw 1#1#2#3#4#5#6; { \if_int_compare:w #1#2 = \c_zero \exp_after:wN \__fp_sqrt_auxx_o:Nnnnnnnn \fi: \__fp_sqrt_auxviii_o:nnnnnnn {00000000} {000#1#2#3#4#5} } \cs_new:Npn \__fp_sqrt_auxviii_o:nnnnnnn #1#2 #3#4#5#6#7 { \exp_after:wN \__fp_sqrt_auxix_o:wnwnw \int_use:N \__int_eval:w #3 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w #1 + 1#4#5 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w #2 + 1#6#7 ; } \cs_new:Npn \__fp_sqrt_auxix_o:wnwnw #1; #2#3; #4#5; { \__fp_sqrt_auxii_o:NnnnnnnnN \__fp_sqrt_auxiii_o:wnnnnnnnn {#1}{#2}{#3}{#4}{#5} } \cs_new:Npn \__fp_sqrt_auxx_o:Nnnnnnnn #1#2#3 #4#5#6#7#8 { \exp_after:wN \__fp_sqrt_auxxi_o:wwnnN \int_use:N \__int_eval:w (#8 + 2499) / 5000 * 5000 ; {#4} {#5} {#6} {#7} ; } \cs_new:Npn \__fp_sqrt_auxxi_o:wwnnN #1; #2; #3#4#5 { \__fp_sqrt_auxii_o:NnnnnnnnN \__fp_sqrt_auxxii_o:nnnnnnnnw #2 {#1} {#3} { #4 + \c_one } #5 } \cs_new:Npn \__fp_sqrt_auxxii_o:nnnnnnnnw 0; #1#2#3#4#5#6#7#8 #9; { \if_int_compare:w #1#2 > \c_zero \if_int_compare:w #1#2 = \c_one \if_int_compare:w #3#4 = \c_zero \if_int_compare:w #5#6 = \c_zero \if_int_compare:w #7#8 = \c_zero \__fp_sqrt_auxxiii_o:w \fi: \fi: \fi: \fi: \exp_after:wN \__fp_sqrt_auxxiv_o:wnnnnnnnN \__int_value:w 9998 \else: \exp_after:wN \__fp_sqrt_auxxiv_o:wnnnnnnnN \__int_value:w 10000 \fi: ; } \cs_new:Npn \__fp_sqrt_auxxiii_o:w \fi: \fi: \fi: \fi: #1 \fi: ; { \fi: \fi: \fi: \fi: \fi: \__fp_sqrt_auxxiv_o:wnnnnnnnN 9999 ; } \cs_new:Npn \__fp_sqrt_auxxiv_o:wnnnnnnnN #1; #2#3#4#5#6 #7#8#9 { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1 0000 0000 + #2#3 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 1 0000 0000 + #4#5 \if_int_compare:w #6 > #1 \exp_stop_f: + \c_one \fi: + \exp_after:wN \__fp_round:NNN \exp_after:wN 0 \exp_after:wN 0 \__int_value:w \exp_after:wN \use_i:nn \exp_after:wN \__fp_round_digit:Nw \int_use:N \__int_eval:w #6 + 19999 - #1 ; \exp_after:wN ; } \cs_new:Npn \__fp_set_sign_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \exp_after:wN \__fp_exp_after_o:w \exp_after:wN \s__fp \exp_after:wN \__fp_chk:w \exp_after:wN #2 \__int_value:w \if_case:w #3 \exp_stop_f: #1 \or: 1 \or: 0 \fi: \exp_stop_f: #4; } %% File: l3fp-extended.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \tl_const:Nn \c__fp_one_fixed_tl { {10000} {0000} {0000} {0000} {0000} {0000} } \cs_new:Npn \__fp_fixed_continue:wn #1; #2 { #2 #1; } \cs_new:Npn \__fp_fixed_add_one:wN #1#2; #3 { \exp_after:wN #3 \exp_after:wN { \int_use:N \__int_eval:w \c_ten_thousand + #1 } #2 ; } \cs_new:Npn \__fp_fixed_div_myriad:wn #1#2#3#4#5#6; { \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_leading_shift_int \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #1 ; {#2}{#3}{#4}{#5}; } \cs_new:Npn \__fp_fixed_mul_after:wwn #1; #2; #3 { #3 {#1} #2; } \cs_new:Npn \__fp_fixed_mul_short:wwn #1#2#3#4#5#6; #7#8#9; { \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_leading_shift_int + #1*#7 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#8 + #2*#7 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#9 + #2*#8 + #3*#7 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #2*#9 + #3*#8 + #4*#7 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #3*#9 + #4*#8 + #5*#7 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #4*#9 + #5*#8 + #6*#7 + ( #5*#9 + #6*#8 + #6*#9 / \c_ten_thousand ) / \c_ten_thousand ; ; } \cs_new:Npn \__fp_fixed_div_int:wwN #1#2#3#4#5#6 ; #7 ; #8 { \exp_after:wN \__fp_fixed_div_int_after:Nw \exp_after:wN #8 \int_use:N \__int_eval:w \c_minus_one \__fp_fixed_div_int:wnN #1; {#7} \__fp_fixed_div_int_auxi:wnn #2; {#7} \__fp_fixed_div_int_auxi:wnn #3; {#7} \__fp_fixed_div_int_auxi:wnn #4; {#7} \__fp_fixed_div_int_auxi:wnn #5; {#7} \__fp_fixed_div_int_auxi:wnn #6; {#7} \__fp_fixed_div_int_auxii:wnn ; } \cs_new:Npn \__fp_fixed_div_int:wnN #1; #2 #3 { \exp_after:wN #3 \int_use:N \__int_eval:w #1 / #2 - \c_one ; {#2} {#1} } \cs_new:Npn \__fp_fixed_div_int_auxi:wnn #1; #2 #3 { + #1 \exp_after:wN \__fp_fixed_div_int_pack:Nw \int_use:N \__int_eval:w 9999 \exp_after:wN \__fp_fixed_div_int:wnN \int_use:N \__int_eval:w #3 - #1*#2 \__int_eval_end: } \cs_new:Npn \__fp_fixed_div_int_auxii:wnn #1; #2 #3 { + #1 + \c_two ; } \cs_new:Npn \__fp_fixed_div_int_pack:Nw #1 #2; { + #1; {#2} } \cs_new:Npn \__fp_fixed_div_int_after:Nw #1 #2; { #1 {#2} } \cs_new_nopar:Npn \__fp_fixed_add:wwn { \__fp_fixed_add:Nnnnnwnn + } \cs_new_nopar:Npn \__fp_fixed_sub:wwn { \__fp_fixed_add:Nnnnnwnn - } \cs_new:Npn \__fp_fixed_add:Nnnnnwnn #1 #2#3#4#5 #6; #7#8 { \exp_after:wN \__fp_fixed_add_after:NNNNNwn \int_use:N \__int_eval:w 9 9999 9998 + #2#3 #1 #7#8 \exp_after:wN \__fp_fixed_add_pack:NNNNNwn \int_use:N \__int_eval:w 1 9999 9998 + #4#5 \__fp_fixed_add:nnNnnnwn #6 #1 } \cs_new:Npn \__fp_fixed_add:nnNnnnwn #1#2 #3 #4#5 #6#7 ; #8 { #3 #4#5 \exp_after:wN \__fp_fixed_add_pack:NNNNNwn \int_use:N \__int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ; } \cs_new:Npn \__fp_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6; #7 { + #1 ; {#7} {#2#3#4#5} {#6} } \cs_new:Npn \__fp_fixed_add_after:NNNNNwn 1 #1 #2#3#4#5 #6; #7 { #7 {#1#2#3#4#5} {#6} } \cs_new:Npn \__fp_fixed_mul:wwn #1#2#3#4 #5; #6#7#8#9 { \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_leading_shift_int \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#6 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#7 + #2*#6 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#8 + #2*#7 + #3*#6 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#9 + #2*#8 + #3*#7 + #4*#6 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #2*#9 + #3*#8 + #4*#7 + ( #3*#9 + #4*#8 + \__fp_fixed_mul:nnnnnnnw #5 {#6}{#7} {#1}{#2} } \cs_new:Npn \__fp_fixed_mul:nnnnnnnw #1#2 #3#4 #5#6 #7#8 ; { #1*#4 + #2*#3 + #5*#8 + #6*#7 ) / \c_ten_thousand + #1*#3 + #5*#7 ; ; } \cs_new:Npn \__fp_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8; { \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_big_leading_shift_int \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #3 #4 \__fp_fixed_mul_add:Nwnnnwnnn + + #5 #6 ; #2 ; #1 ; #2 ; + + #7 #8 ; ; } \cs_new:Npn \__fp_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8; { \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_big_leading_shift_int \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #3 #4 \__fp_fixed_mul_add:Nwnnnwnnn - + #5 #6 ; #2 ; #1 ; #2 ; - + #7 #8 ; ; } \cs_new:Npn \__fp_fixed_one_minus_mul:wwn #1; #2; { \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_big_leading_shift_int \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + 1 0000 0000 \__fp_fixed_mul_add:Nwnnnwnnn - ; #2 ; #1 ; #2 ; - ; ; } \cs_new:Npn \__fp_fixed_mul_add:Nwnnnwnnn #1 #2; #3#4#5#6; #7#8#9 { #1 #7*#3 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int #1 #7*#4 #1 #8*#3 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int #1 #7*#5 #1 #8*#4 #1 #9*#3 #2 \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_middle_shift_int #1 \__fp_fixed_mul_add:nnnnwnnnn {#7}{#8}{#9} } \cs_new:Npn \__fp_fixed_mul_add:nnnnwnnnn #1#2#3#4#5; #6#7#8#9 { ( #1*#9 + #2*#8 + #3*#7 + #4*#6 ) \exp_after:wN \__fp_pack_big:NNNNNNw \int_use:N \__int_eval:w \c__fp_big_trailing_shift_int \__fp_fixed_mul_add:nnnnwnnwN { #6 + #4*#7 + #3*#8 + #2*#9 + #1 } { #7 + #4*#8 + #3*#9 + #2 } {#1} #5; {#6} } \cs_new:Npn \__fp_fixed_mul_add:nnnnwnnwN #1#2 #3#4#5; #6#7#8; #9 { #9 (#4* #1 *#7) #9 (#5*#6+#4* #2 *#7+#3*#8) / \c_ten_thousand } \cs_new:Npn \__fp_ep_to_fixed:wwn #1,#2 { \exp_after:wN \__fp_ep_to_fixed_auxi:www \int_use:N \__int_eval:w 1 0000 0000 + #2 \exp_after:wN ; \tex_romannumeral:D -`0 \prg_replicate:nn { \c_four - \int_max:nn {#1} { -32 } } { 0 } ; } \cs_new:Npn \__fp_ep_to_fixed_auxi:www 1#1; #2; #3#4#5#6#7; { \__fp_pack_eight:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_ep_to_fixed_auxii:nnnnnnnwn ; #2 #1#3#4#5#6#7 0000 ! } \cs_new:Npn \__fp_ep_to_fixed_auxii:nnnnnnnwn #1#2#3#4#5#6#7; #8! #9 { #9 {#1#2}{#3}{#4}{#5}{#6}{#7}; } \cs_new:Npn \__fp_ep_to_ep:wwN #1,#2#3#4#5#6#7; #8 { \exp_after:wN #8 \int_use:N \__int_eval:w #1 + \c_four \exp_after:wN \use_i:nn \exp_after:wN \__fp_ep_to_ep_loop:N \int_use:N \__int_eval:w 1 0000 0000 + #2 \__int_eval_end: #3#4#5#6#7 ; ; ! } \cs_new:Npn \__fp_ep_to_ep_loop:N #1 { \if_meaning:w 0 #1 - \c_one \else: \__fp_ep_to_ep_end:www #1 \fi: \__fp_ep_to_ep_loop:N } \cs_new:Npn \__fp_ep_to_ep_end:www #1 \fi: \__fp_ep_to_ep_loop:N #2; #3! { \fi: \if_meaning:w ; #1 - \c_two * \c__fp_max_exponent_int \__fp_ep_to_ep_zero:ww \fi: \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_use_i:ww , ; #1 #2 0000 0000 0000 0000 0000 0000 ; } \cs_new:Npn \__fp_ep_to_ep_zero:ww \fi: #1; #2; #3; { \fi: , {1000}{0000}{0000}{0000}{0000}{0000} ; } \cs_new:Npn \__fp_ep_compare:wwww #1,#2#3#4#5#6#7; { \__fp_ep_compare_aux:wwww {#1}{#2}{#3}{#4}{#5}; #6#7; } \cs_new:Npn \__fp_ep_compare_aux:wwww #1;#2;#3,#4#5#6#7#8#9; { \if_case:w \__fp_compare_npos:nwnw #1; {#3}{#4}{#5}{#6}{#7}; \exp_stop_f: \if_int_compare:w #2 = #8#9 \exp_stop_f: 0 \else: \if_int_compare:w #2 < #8#9 - \fi: 1 \fi: \or: 1 \else: -1 \fi: } \cs_new:Npn \__fp_ep_mul:wwwwn #1,#2; #3,#4; { \__fp_ep_to_ep:wwN #3,#4; \__fp_fixed_continue:wn { \__fp_ep_to_ep:wwN #1,#2; \__fp_ep_mul_raw:wwwwN } \__fp_fixed_continue:wn } \cs_new:Npn \__fp_ep_mul_raw:wwwwN #1,#2; #3,#4; #5 { \__fp_fixed_mul:wwn #2; #4; { \exp_after:wN #5 \int_use:N \__int_eval:w #1 + #3 , } } \cs_new:Npn \__fp_ep_div:wwwwn #1,#2; #3,#4; { \__fp_ep_to_ep:wwN #1,#2; \__fp_fixed_continue:wn { \__fp_ep_to_ep:wwN #3,#4; \__fp_ep_div_esti:wwwwn } } \cs_new:Npn \__fp_ep_div_esti:wwwwn #1,#2#3; #4, { \exp_after:wN \__fp_ep_div_estii:wwnnwwn \int_use:N \__int_eval:w 10 0000 0000 / ( #2 + \c_one ) \exp_after:wN ; \int_use:N \__int_eval:w #4 - #1 + \c_one , {#2} #3; } \cs_new:Npn \__fp_ep_div_estii:wwnnwwn #1; #2,#3#4#5; #6; #7 { \exp_after:wN \__fp_ep_div_estiii:NNNNNwwwn \int_use:N \__int_eval:w 10 0000 0000 - 1750 + #1 000 + (10 0000 0000 / #3 - #1) * (1000 - #4 / 10) ; {#3}{#4}#5; #6; { #7 #2, } } \cs_new:Npn \__fp_ep_div_estiii:NNNNNwwwn 1#1#2#3#4#5#6; #7; { \__fp_fixed_mul_short:wwn #7; {#1}{#2#3#4#5}{#6}; \__fp_ep_div_epsi:wnNNNNNn {#1#2#3#4}#5#6 \__fp_fixed_mul:wwn } \cs_new:Npn \__fp_ep_div_epsi:wnNNNNNn #1#2#3#4#5#6; { \exp_after:wN \__fp_ep_div_epsii:wwnNNNNNn \int_use:N \__int_eval:w 1 9998 - #2 \exp_after:wN \__fp_ep_div_eps_pack:NNNNNw \int_use:N \__int_eval:w 1 9999 9998 - #3#4 \exp_after:wN \__fp_ep_div_eps_pack:NNNNNw \int_use:N \__int_eval:w 2 0000 0000 - #5#6 ; ; } \cs_new:Npn \__fp_ep_div_eps_pack:NNNNNw #1#2#3#4#5#6; { + #1 ; {#2#3#4#5} {#6} } \cs_new:Npn \__fp_ep_div_epsii:wwnNNNNNn 1#1; #2; #3#4#5#6#7#8 { \__fp_fixed_mul:wwn {0000}{#1}#2; {0000}{#1}#2; \__fp_fixed_add_one:wN \__fp_fixed_mul:wwn {10000} {#1} #2 ; { \__fp_fixed_mul_short:wwn {0000}{#1}#2; {#3}{#4#5#6#7}{#8000}; \__fp_fixed_div_myriad:wn \__fp_fixed_mul:wwn } \__fp_fixed_add:wwn {#3}{#4#5#6#7}{#8000}{0000}{0000}{0000}; } \cs_new:Npn \__fp_ep_isqrt:wwn #1,#2; { \__fp_ep_to_ep:wwN #1,#2; \__fp_ep_isqrt_auxi:wwn } \cs_new:Npn \__fp_ep_isqrt_auxi:wwn #1, { \exp_after:wN \__fp_ep_isqrt_auxii:wwnnnwn \int_use:N \__int_eval:w \int_if_odd:nTF {#1} { (\c_one - #1) / \c_two , 535 , { 0 } { } } { \c_one - #1 / \c_two , 168 , { } { 0 } } } \cs_new:Npn \__fp_ep_isqrt_auxii:wwnnnwn #1, #2, #3#4 #5#6; #7 { \__fp_ep_isqrt_esti:wwwnnwn #2, 0, #5, {#3} {#4} {#5} #6 ; { #7 #1 , } } \cs_new:Npn \__fp_ep_isqrt_esti:wwwnnwn #1, #2, #3, #4 { \if_int_compare:w #1 = #2 \exp_stop_f: \exp_after:wN \__fp_ep_isqrt_estii:wwwnnwn \fi: \exp_after:wN \__fp_ep_isqrt_esti:wwwnnwn \int_use:N \__int_eval:w (#1 + 1 0050 0000 #4 / (#1 * #3)) / \c_two , #1, #3, {#4} } \cs_new:Npn \__fp_ep_isqrt_estii:wwwnnwn #1, #2, #3, #4#5 { \exp_after:wN \__fp_ep_isqrt_estiii:NNNNNwwwn \int_use:N \__int_eval:w 1000 0000 + #2 * #2 #5 * \c_five \exp_after:wN , \int_use:N \__int_eval:w 10000 + #2 ; } \cs_new:Npn \__fp_ep_isqrt_estiii:NNNNNwwwn 1#1#2#3#4#5#6, 1#7#8; #9; { \__fp_fixed_mul_short:wwn #9; {#1} {#2#3#4#5} {#600} ; \__fp_ep_isqrt_epsi:wN \__fp_fixed_mul_short:wwn {#7} {#80} {0000} ; } \cs_new:Npn \__fp_ep_isqrt_epsi:wN #1; { \__fp_fixed_sub:wwn {15000}{0000}{0000}{0000}{0000}{0000}; #1; \__fp_ep_isqrt_epsii:wwN #1; \__fp_ep_isqrt_epsii:wwN #1; \__fp_ep_isqrt_epsii:wwN #1; } \cs_new:Npn \__fp_ep_isqrt_epsii:wwN #1; #2; { \__fp_fixed_mul:wwn #1; #1; \__fp_fixed_mul_sub_back:wwwn #2; {15000}{0000}{0000}{0000}{0000}{0000}; \__fp_fixed_mul:wwn #1; } \cs_new:Npn \__fp_ep_to_float:wwN #1, { + \__int_eval:w #1 \__fp_fixed_to_float:wN } \cs_new:Npn \__fp_ep_inv_to_float:wwN #1,#2; { \__fp_ep_div:wwwwn 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1,#2; \__fp_ep_to_float:wwN } \cs_new:Npn \__fp_fixed_inv_to_float:wN { \__fp_ep_inv_to_float:wwN 0, } \cs_new:Npn \__fp_fixed_to_float_rad:wN #1; { \__fp_fixed_mul:wwn #1; {5729}{5779}{5130}{8232}{0876}{7981}; { \__fp_ep_to_float:wwN 2, } } \cs_new:Npn \__fp_fixed_to_float:Nw #1#2; { \__fp_fixed_to_float:wN #2; #1 } \cs_new:Npn \__fp_fixed_to_float:wN #1#2#3#4#5#6; #7 { + \__int_eval:w \c_four % for the 8-digit-at-the-start thing. \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_to_loop:N \exp_after:wN \use_none:n \int_use:N \__int_eval:w 1 0000 0000 + #1 \exp_after:wN \__fp_use_none_stop_f:n \__int_value:w 1#2 \exp_after:wN \__fp_use_none_stop_f:n \__int_value:w 1#3#4 \exp_after:wN \__fp_use_none_stop_f:n \__int_value:w 1#5#6 \exp_after:wN ; \exp_after:wN ; } \cs_new:Npn \__fp_fixed_to_loop:N #1 { \if_meaning:w 0 #1 - \c_one \exp_after:wN \__fp_fixed_to_loop:N \else: \exp_after:wN \__fp_fixed_to_loop_end:w \exp_after:wN #1 \fi: } \cs_new:Npn \__fp_fixed_to_loop_end:w #1 #2 ; { \if_meaning:w ; #1 \exp_after:wN \__fp_fixed_to_float_zero:w \else: \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_fixed_to_float_pack:ww \exp_after:wN ; \fi: #1 #2 0000 0000 0000 0000 ; } \cs_new:Npn \__fp_fixed_to_float_zero:w ; 0000 0000 0000 0000 ; { - \c_two * \c__fp_max_exponent_int ; {0000} {0000} {0000} {0000} ; } \cs_new:Npn \__fp_fixed_to_float_pack:ww #1 ; #2#3 ; ; { \if_int_compare:w #2 > \c_four \exp_after:wN \__fp_fixed_to_float_round_up:wnnnnw \fi: ; #1 ; } \cs_new:Npn \__fp_fixed_to_float_round_up:wnnnnw ; #1#2#3#4 ; { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1 #1#2 \exp_after:wN \__fp_basics_pack_low:NNNNNw \int_use:N \__int_eval:w 1 #3#4 + \c_one ; } %% File: l3fp-expo.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \tl_const:Nn \c__fp_ln_i_fixed_tl { {0000}{0000}{0000}{0000}{0000}{0000} } \tl_const:Nn \c__fp_ln_ii_fixed_tl { {6931}{4718}{0559}{9453}{0941}{7232} } \tl_const:Nn \c__fp_ln_iii_fixed_tl {{10986}{1228}{8668}{1096}{9139}{5245} } \tl_const:Nn \c__fp_ln_iv_fixed_tl {{13862}{9436}{1119}{8906}{1883}{4464} } \tl_const:Nn \c__fp_ln_vi_fixed_tl {{17917}{5946}{9228}{0550}{0081}{2477} } \tl_const:Nn \c__fp_ln_vii_fixed_tl {{19459}{1014}{9055}{3133}{0510}{5353} } \tl_const:Nn \c__fp_ln_viii_fixed_tl{{20794}{4154}{1679}{8359}{2825}{1696} } \tl_const:Nn \c__fp_ln_ix_fixed_tl {{21972}{2457}{7336}{2193}{8279}{0490} } \tl_const:Nn \c__fp_ln_x_fixed_tl {{23025}{8509}{2994}{0456}{8401}{7991} } \cs_new:Npn \__fp_ln_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_meaning:w 2 #3 \__fp_case_use:nw { \__fp_invalid_operation_o:nw { ln } } \fi: \if_case:w #2 \exp_stop_f: \__fp_case_use:nw { \__fp_division_by_zero_o:Nnw \c_minus_inf_fp { ln } } \or: \else: \__fp_case_return_same_o:w \fi: \__fp_ln_npos_o:w \s__fp \__fp_chk:w #2#3#4; } \cs_new:Npn \__fp_ln_npos_o:w \s__fp \__fp_chk:w 10#1#2#3; { %^^A todo: ln(1) should be "exact zero", not "underflow" \exp_after:wN \__fp_sanitize:Nw \__int_value:w % for the overall sign \if_int_compare:w #1 < \c_one 2 \else: 0 \fi: \exp_after:wN \exp_stop_f: \int_use:N \__int_eval:w % for the exponent \__fp_ln_significand:NNNNnnnN #2#3 \__fp_ln_exponent:wn {#1} } \cs_new:Npn \__fp_ln_significand:NNNNnnnN #1#2#3#4 { \exp_after:wN \__fp_ln_x_ii:wnnnn \__int_value:w \if_case:w #1 \exp_stop_f: \or: \if_int_compare:w #2 < \c_four \__int_eval:w \c_ten - #2 \else: 6 \fi: \or: 4 \or: 3 \or: 2 \or: 2 \or: 2 \else: 1 \fi: ; { #1 #2 #3 #4 } } \cs_new:Npn \__fp_ln_x_ii:wnnnn #1; #2#3#4#5 { \exp_after:wN \__fp_ln_div_after:Nw \cs:w c__fp_ln_ \tex_romannumeral:D #1 _fixed_tl \exp_after:wN \cs_end: \__int_value:w \exp_after:wN \__fp_ln_x_iv:wnnnnnnnn \int_use:N \__int_eval:w \exp_after:wN \__fp_ln_x_iii_var:NNNNNw \int_use:N \__int_eval:w 9999 9999 + #1*#2#3 + \exp_after:wN \__fp_ln_x_iii:NNNNNw \int_use:N \__int_eval:w 1 0000 0000 + #1*#4#5 ; {20000} {0000} {0000} {0000} } %^^A todo: reoptimize (a generalization attempt failed). \cs_new:Npn \__fp_ln_x_iii:NNNNNw #1 #2#3#4#5 #6; { #1; {#2#3#4#5} {#6} } \cs_new:Npn \__fp_ln_x_iii_var:NNNNNw #1 #2#3#4#5 #6; { #1#2#3#4#5 + \c_one ; {#1#2#3#4#5} {#6} } \cs_new:Npn \__fp_ln_x_iv:wnnnnnnnn #1; #2#3#4#5 #6#7#8#9 { \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w \__fp_ln_div_i:w #1 ; #6 #7 ; {#8} {#9} {#2} {#3} {#4} {#5} { \exp_after:wN \__fp_ln_div_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_ln_div_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_ln_div_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_ln_div_ii:wwn \__int_value:w #1 } { \exp_after:wN \__fp_ln_div_vi:wwn \__int_value:w #1 } } \cs_new:Npn \__fp_ln_div_i:w #1; { \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1 } \cs_new:Npn \__fp_ln_div_ii:wwn #1; #2;#3 % y; B1;B2 <- for k=1 { \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 / #1 ; % Q2 #2 #3 ; } \cs_new:Npn \__fp_ln_div_vi:wwn #1; #2;#3#4#5 #6#7#8#9 %y;F1;F2F3F4x1x2x3x4 { \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w 1000000 + #2 #3 / #1 ; % Q6 } \cs_new:Npn \__fp_ln_div_after:Nw #1#2; { \if_meaning:w 0 #2 \exp_after:wN \__fp_ln_t_small:Nw \else: \exp_after:wN \__fp_ln_t_large:NNw \exp_after:wN - \fi: #1 } \cs_new:Npn \__fp_ln_t_small:Nw #1 #2; #3; #4; #5; #6; #7; { \exp_after:wN \__fp_ln_t_large:NNw \exp_after:wN + % \exp_after:wN #1 \int_use:N \__int_eval:w 9999 - #2 \exp_after:wN ; \int_use:N \__int_eval:w 9999 - #3 \exp_after:wN ; \int_use:N \__int_eval:w 9999 - #4 \exp_after:wN ; \int_use:N \__int_eval:w 9999 - #5 \exp_after:wN ; \int_use:N \__int_eval:w 9999 - #6 \exp_after:wN ; \int_use:N \__int_eval:w 1 0000 - #7 ; } \cs_new:Npn \__fp_ln_t_large:NNw #1 #2 #3; #4; #5; #6; #7; #8; { \exp_after:wN \__fp_ln_square_t_after:w \int_use:N \__int_eval:w 9999 0000 + #3*#3 \exp_after:wN \__fp_ln_square_t_pack:NNNNNw \int_use:N \__int_eval:w 9999 0000 + 2*#3*#4 \exp_after:wN \__fp_ln_square_t_pack:NNNNNw \int_use:N \__int_eval:w 9999 0000 + 2*#3*#5 + #4*#4 \exp_after:wN \__fp_ln_square_t_pack:NNNNNw \int_use:N \__int_eval:w 9999 0000 + 2*#3*#6 + 2*#4*#5 \exp_after:wN \__fp_ln_square_t_pack:NNNNNw \int_use:N \__int_eval:w 1 0000 0000 + 2*#3*#7 + 2*#4*#6 + #5*#5 + (2*#3*#8 + 2*#4*#7 + 2*#5*#6) / 1 0000 % ; ; ; \exp_after:wN \__fp_ln_twice_t_after:w \int_use:N \__int_eval:w -1 + 2*#3 \exp_after:wN \__fp_ln_twice_t_pack:Nw \int_use:N \__int_eval:w 9999 + 2*#4 \exp_after:wN \__fp_ln_twice_t_pack:Nw \int_use:N \__int_eval:w 9999 + 2*#5 \exp_after:wN \__fp_ln_twice_t_pack:Nw \int_use:N \__int_eval:w 9999 + 2*#6 \exp_after:wN \__fp_ln_twice_t_pack:Nw \int_use:N \__int_eval:w 9999 + 2*#7 \exp_after:wN \__fp_ln_twice_t_pack:Nw \int_use:N \__int_eval:w 10000 + 2*#8 ; ; { \__fp_ln_c:NwNw #1 } #2 } \cs_new:Npn \__fp_ln_twice_t_pack:Nw #1 #2; { + #1 ; {#2} } \cs_new:Npn \__fp_ln_twice_t_after:w #1; { ;;; {#1} } \cs_new:Npn \__fp_ln_square_t_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} } \cs_new:Npn \__fp_ln_square_t_after:w 1 0 #1#2#3 #4; { \__fp_ln_Taylor:wwNw {0#1#2#3} {#4} } \cs_new:Npn \__fp_ln_Taylor:wwNw { \__fp_ln_Taylor_loop:www 21 ; {0000}{0000}{0000}{0000}{0000}{0000} ; } \cs_new:Npn \__fp_ln_Taylor_loop:www #1; #2; #3; { \if_int_compare:w #1 = \c_one \__fp_ln_Taylor_break:w \fi: \exp_after:wN \__fp_fixed_div_int:wwN \c__fp_one_fixed_tl ; #1; \__fp_fixed_add:wwn #2; \__fp_fixed_mul:wwn #3; { \exp_after:wN \__fp_ln_Taylor_loop:www \int_use:N \__int_eval:w #1 - \c_two ; } #3; } \cs_new:Npn \__fp_ln_Taylor_break:w \fi: #1 \__fp_fixed_add:wwn #2#3; #4 ;; { \fi: \exp_after:wN \__fp_fixed_mul:wwn \exp_after:wN { \int_use:N \__int_eval:w 10000 + #2 } #3; } \cs_new:Npn \__fp_ln_c:NwNw #1 #2; #3 { \if_meaning:w + #1 \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_sub:wwn \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_add:wwn \fi: #3 ; #2 ; } \cs_new:Npn \__fp_ln_exponent:wn #1; #2 { \if_case:w #2 \exp_stop_f: \c_zero \__fp_case_return:nw { \__fp_fixed_to_float:Nw 2 } \or: \exp_after:wN \__fp_ln_exponent_one:ww \__int_value:w \else: \if_int_compare:w #2 > \c_zero \exp_after:wN \__fp_ln_exponent_small:NNww \exp_after:wN 0 \exp_after:wN \__fp_fixed_sub:wwn \__int_value:w \else: \exp_after:wN \__fp_ln_exponent_small:NNww \exp_after:wN 2 \exp_after:wN \__fp_fixed_add:wwn \__int_value:w - \fi: \fi: #2; #1; } \cs_new:Npn \__fp_ln_exponent_one:ww 1; #1; { \c_zero \exp_after:wN \__fp_fixed_sub:wwn \c__fp_ln_x_fixed_tl ; #1; \__fp_fixed_to_float:wN 0 } \cs_new:Npn \__fp_ln_exponent_small:NNww #1#2#3; #4#5#6#7#8#9; { \c_four \exp_after:wN \__fp_fixed_mul:wwn \c__fp_ln_x_fixed_tl ; {#3}{0000}{0000}{0000}{0000}{0000} ; #2 {0000}{#4}{#5}{#6}{#7}{#8}; \__fp_fixed_to_float:wN #1 } \cs_new:Npn \__fp_exp_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_case:w #2 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: \exp_after:wN \__fp_exp_normal:w \or: \if_meaning:w 0 #3 \exp_after:wN \__fp_case_return_o:Nw \exp_after:wN \c_inf_fp \else: \exp_after:wN \__fp_case_return_o:Nw \exp_after:wN \c_zero_fp \fi: \or: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2#3#4; } \cs_new:Npn \__fp_exp_normal:w \s__fp \__fp_chk:w 1#1 { \if_meaning:w 0 #1 \__fp_exp_pos:NNwnw + \__fp_fixed_to_float:wN \else: \__fp_exp_pos:NNwnw - \__fp_fixed_inv_to_float:wN \fi: } \cs_new:Npn \__fp_exp_pos:NNwnw #1#2#3 \fi: #4#5; { \fi: \exp_after:wN \__fp_sanitize:Nw \exp_after:wN 0 \__int_value:w #1 \__int_eval:w \if_int_compare:w #4 < - \c_eight \c_one \exp_after:wN \__fp_add_big_i_o:wNww \int_use:N \__int_eval:w \c_one - #4 ; 0 {1000}{0000}{0000}{0000} ; #5; \tex_romannumeral:D \else: \if_int_compare:w #4 > \c_five % cf \c__fp_max_exponent_int \exp_after:wN \__fp_exp_overflow: \tex_romannumeral:D \else: \if_int_compare:w #4 < \c_zero \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: { \c_zero \__fp_decimate:nNnnnn { - #4 } \__fp_exp_Taylor:Nnnwn } { \__fp_decimate:nNnnnn { \c_sixteen - #4 } \__fp_exp_pos_large:NnnNwn } #5 {#4} #1 #2 0 \tex_romannumeral:D \fi: \fi: \exp_after:wN \c_zero } \cs_new:Npn \__fp_exp_overflow: { + \c_two * \c__fp_max_exponent_int ; {1000} {0000} {0000} {0000} ; } \cs_new:Npn \__fp_exp_Taylor:Nnnwn #1#2#3 #4; #5 #6 { #6 \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_exp_Taylor_ii:ww ; #2#3#4 0000 0000 ; } \cs_new:Npn \__fp_exp_Taylor_ii:ww #1; #2; { \__fp_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s__stop } \cs_new:Npn \__fp_exp_Taylor_loop:www #1; #2; #3; { \if_int_compare:w #1 = \c_one \exp_after:wN \__fp_exp_Taylor_break:Nww \fi: \__fp_fixed_div_int:wwN #3 ; #1 ; \__fp_fixed_add_one:wN \__fp_fixed_mul:wwn #2 ; { \exp_after:wN \__fp_exp_Taylor_loop:www \int_use:N \__int_eval:w #1 - 1 ; #2 ; } } \cs_new:Npn \__fp_exp_Taylor_break:Nww #1 #2; #3 \s__stop { \__fp_fixed_add_one:wN #2 ; } \cs_new:Npn \__fp_exp_pos_large:NnnNwn #1#2#3 #4#5; #6 { \exp_after:wN \exp_after:wN \cs:w __fp_exp_large_\tex_romannumeral:D #6:wN \exp_after:wN \cs_end: \exp_after:wN \c__fp_one_fixed_tl \exp_after:wN ; \__int_value:w #3 #4 \exp_stop_f: #5 00000 ; } \cs_new:Npn \__fp_exp_large:w #1 \or: #2 \fi: { \fi: \__fp_fixed_mul:wwn #1; } \cs_new:Npn \__fp_exp_large_v:wN #1; #2 { \if_case:w #2 ~ \exp_after:wN \__fp_fixed_continue:wn \or: + 4343 \__fp_exp_large:w {8806}{8182}{2566}{2921}{5872}{6150} \or: + 8686 \__fp_exp_large:w {7756}{0047}{2598}{6861}{0458}{3204} \or: + 13029 \__fp_exp_large:w {6830}{5723}{7791}{4884}{1932}{7351} \or: + 17372 \__fp_exp_large:w {6015}{5609}{3095}{3052}{3494}{7574} \or: + 21715 \__fp_exp_large:w {5297}{7951}{6443}{0315}{3251}{3576} \or: + 26058 \__fp_exp_large:w {4665}{6719}{0099}{3379}{5527}{2929} \or: + 30401 \__fp_exp_large:w {4108}{9724}{3326}{3186}{5271}{5665} \or: + 34744 \__fp_exp_large:w {3618}{6973}{3140}{0875}{3856}{4102} \or: + 39087 \__fp_exp_large:w {3186}{9209}{6113}{3900}{6705}{9685} \or: \fi: #1; \__fp_exp_large_iv:wN } \cs_new:Npn \__fp_exp_large_iv:wN #1; #2 { \if_case:w #2 ~ \exp_after:wN \__fp_fixed_continue:wn \or: + 435 \__fp_exp_large:w {1970}{0711}{1401}{7046}{9938}{8888} \or: + 869 \__fp_exp_large:w {3881}{1801}{9428}{4368}{5764}{8232} \or: + 1303 \__fp_exp_large:w {7646}{2009}{8905}{4704}{8893}{1073} \or: + 1738 \__fp_exp_large:w {1506}{3559}{7005}{0524}{9009}{7592} \or: + 2172 \__fp_exp_large:w {2967}{6283}{8402}{3667}{0689}{6630} \or: + 2606 \__fp_exp_large:w {5846}{4389}{5650}{2114}{7278}{5046} \or: + 3041 \__fp_exp_large:w {1151}{7900}{5080}{6878}{2914}{4154} \or: + 3475 \__fp_exp_large:w {2269}{1083}{0850}{6857}{8724}{4002} \or: + 3909 \__fp_exp_large:w {4470}{3047}{3316}{5442}{6408}{6591} \or: \fi: #1; \__fp_exp_large_iii:wN } \cs_new:Npn \__fp_exp_large_iii:wN #1; #2 { \if_case:w #2 ~ \exp_after:wN \__fp_fixed_continue:wn \or: + 44 \__fp_exp_large:w {2688}{1171}{4181}{6135}{4484}{1263} \or: + 87 \__fp_exp_large:w {7225}{9737}{6812}{5749}{2581}{7748} \or: + 131 \__fp_exp_large:w {1942}{4263}{9524}{1255}{9365}{8421} \or: + 174 \__fp_exp_large:w {5221}{4696}{8976}{4143}{9505}{8876} \or: + 218 \__fp_exp_large:w {1403}{5922}{1785}{2837}{4107}{3977} \or: + 261 \__fp_exp_large:w {3773}{0203}{0092}{9939}{8234}{0143} \or: + 305 \__fp_exp_large:w {1014}{2320}{5473}{5004}{5094}{5533} \or: + 348 \__fp_exp_large:w {2726}{3745}{7211}{2566}{5673}{6478} \or: + 391 \__fp_exp_large:w {7328}{8142}{2230}{7421}{7051}{8866} \or: \fi: #1; \__fp_exp_large_ii:wN } \cs_new:Npn \__fp_exp_large_ii:wN #1; #2 { \if_case:w #2 ~ \exp_after:wN \__fp_fixed_continue:wn \or: + 5 \__fp_exp_large:w {2202}{6465}{7948}{0671}{6516}{9579} \or: + 9 \__fp_exp_large:w {4851}{6519}{5409}{7902}{7796}{9107} \or: + 14 \__fp_exp_large:w {1068}{6474}{5815}{2446}{2146}{9905} \or: + 18 \__fp_exp_large:w {2353}{8526}{6837}{0199}{8540}{7900} \or: + 22 \__fp_exp_large:w {5184}{7055}{2858}{7072}{4640}{8745} \or: + 27 \__fp_exp_large:w {1142}{0073}{8981}{5684}{2836}{6296} \or: + 31 \__fp_exp_large:w {2515}{4386}{7091}{9167}{0062}{6578} \or: + 35 \__fp_exp_large:w {5540}{6223}{8439}{3510}{0525}{7117} \or: + 40 \__fp_exp_large:w {1220}{4032}{9431}{7840}{8020}{0271} \or: \fi: #1; \__fp_exp_large_i:wN } \cs_new:Npn \__fp_exp_large_i:wN #1; #2 { \if_case:w #2 ~ \exp_after:wN \__fp_fixed_continue:wn \or: + 1 \__fp_exp_large:w {2718}{2818}{2845}{9045}{2353}{6029} \or: + 1 \__fp_exp_large:w {7389}{0560}{9893}{0650}{2272}{3043} \or: + 2 \__fp_exp_large:w {2008}{5536}{9231}{8766}{7740}{9285} \or: + 2 \__fp_exp_large:w {5459}{8150}{0331}{4423}{9078}{1103} \or: + 3 \__fp_exp_large:w {1484}{1315}{9102}{5766}{0342}{1116} \or: + 3 \__fp_exp_large:w {4034}{2879}{3492}{7351}{2260}{8387} \or: + 4 \__fp_exp_large:w {1096}{6331}{5842}{8458}{5992}{6372} \or: + 4 \__fp_exp_large:w {2980}{9579}{8704}{1728}{2747}{4359} \or: + 4 \__fp_exp_large:w {8103}{0839}{2757}{5384}{0077}{1000} \or: \fi: #1; \__fp_exp_large_:wN } \cs_new:Npn \__fp_exp_large_:wN #1; #2 { \if_case:w #2 ~ \exp_after:wN \__fp_fixed_continue:wn \or: + 1 \__fp_exp_large:w {1105}{1709}{1807}{5647}{6248}{1171} \or: + 1 \__fp_exp_large:w {1221}{4027}{5816}{0169}{8339}{2107} \or: + 1 \__fp_exp_large:w {1349}{8588}{0757}{6003}{1039}{8374} \or: + 1 \__fp_exp_large:w {1491}{8246}{9764}{1270}{3178}{2485} \or: + 1 \__fp_exp_large:w {1648}{7212}{7070}{0128}{1468}{4865} \or: + 1 \__fp_exp_large:w {1822}{1188}{0039}{0508}{9748}{7537} \or: + 1 \__fp_exp_large:w {2013}{7527}{0747}{0476}{5216}{2455} \or: + 1 \__fp_exp_large:w {2225}{5409}{2849}{2467}{6045}{7954} \or: + 1 \__fp_exp_large:w {2459}{6031}{1115}{6949}{6638}{0013} \or: \fi: #1; \__fp_exp_large_after:wwn } \cs_new:Npn \__fp_exp_large_after:wwn #1; #2; #3 { \__fp_exp_Taylor:Nnnwn ? { } { } 0 #2; {} #3 \__fp_fixed_mul:wwn #1; } \cs_new:cpn { __fp_ \iow_char:N \^ _o:ww } \s__fp \__fp_chk:w #1#2#3; \s__fp \__fp_chk:w #4#5#6; { \if_meaning:w 0 #4 \__fp_case_return_o:Nw \c_one_fp \fi: \if_case:w #2 \exp_stop_f: \exp_after:wN \use_i:nn \or: \__fp_case_return_o:Nw \c_nan_fp \else: \exp_after:wN \__fp_pow_neg:www \tex_romannumeral:D -`0 \exp_after:wN \use:nn \fi: { \if_meaning:w 1 #1 \exp_after:wN \__fp_pow_normal:ww \else: \exp_after:wN \__fp_pow_zero_or_inf:ww \fi: \s__fp \__fp_chk:w #1#2#3; } { \s__fp \__fp_chk:w #4#5#6; \s__fp \__fp_chk:w #1#2#3; } \s__fp \__fp_chk:w #4#5#6; } \cs_new:Npn \__fp_pow_zero_or_inf:ww \s__fp \__fp_chk:w #1#2; \s__fp \__fp_chk:w #3#4 { \if_meaning:w 1 #4 \__fp_case_return_same_o:w \fi: \if_meaning:w #1 #4 \__fp_case_return_o:Nw \c_zero_fp \fi: \if_meaning:w 0 #1 \__fp_case_use:nw { \__fp_division_by_zero_o:NNww \c_inf_fp ^ \s__fp \__fp_chk:w #1 #2 ; } \else: \__fp_case_return_o:Nw \c_inf_fp \fi: \s__fp \__fp_chk:w #3#4 } \cs_new:Npn \__fp_pow_normal:ww \s__fp \__fp_chk:w 1 #1#2#3; \s__fp \__fp_chk:w #4#5 { \if_int_compare:w \pdftex_strcmp:D { #2 #3 } { 1 {1000} {0000} {0000} {0000} } = \c_zero \if_int_compare:w #4 #1 = 32 \exp_stop_f: \exp_after:wN \__fp_case_return_ii_o:ww \fi: \__fp_case_return_o:Nww \c_one_fp \fi: \if_case:w #4 \exp_stop_f: \or: \exp_after:wN \__fp_pow_npos:Nww \exp_after:wN #5 \or: \if_meaning:w 2 #5 \exp_after:wN \reverse_if:N \fi: \if_int_compare:w #2 > \c_zero \exp_after:wN \__fp_case_return_o:Nww \exp_after:wN \c_inf_fp \else: \exp_after:wN \__fp_case_return_o:Nww \exp_after:wN \c_zero_fp \fi: \or: \__fp_case_return_ii_o:ww \fi: \s__fp \__fp_chk:w 1 #1 {#2} #3 ; \s__fp \__fp_chk:w #4 #5 } \cs_new:Npn \__fp_pow_npos:Nww #1 \s__fp \__fp_chk:w 1#2#3 { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN 0 \__int_value:w \if:w #1 \if_int_compare:w #3 > \c_zero 0 \else: 2 \fi: \exp_after:wN \__fp_pow_npos_aux:NNnww \exp_after:wN + \exp_after:wN \__fp_fixed_to_float:wN \else: \exp_after:wN \__fp_pow_npos_aux:NNnww \exp_after:wN - \exp_after:wN \__fp_fixed_inv_to_float:wN \fi: {#3} } \cs_new:Npn \__fp_pow_npos_aux:NNnww #1#2#3#4#5; \s__fp \__fp_chk:w 1#6#7#8; { #1 \__int_eval:w \__fp_ln_significand:NNNNnnnN #4#5 \__fp_pow_exponent:wnN {#3} \__fp_fixed_mul:wwn #8 {0000}{0000} ; \__fp_pow_B:wwN #7; #1 #2 0 % fixed_to_float:wN } \cs_new:Npn \__fp_pow_exponent:wnN #1; #2 { \if_int_compare:w #2 > \c_zero \exp_after:wN \__fp_pow_exponent:Nwnnnnnw % n\ln(10) - (-\ln(x)) \exp_after:wN + \else: \exp_after:wN \__fp_pow_exponent:Nwnnnnnw % -( |n|\ln(10) + (-\ln(x)) ) \exp_after:wN - \fi: #2; #1; } \cs_new:Npn \__fp_pow_exponent:Nwnnnnnw #1#2; #3#4#5#6#7#8; { %^^A todo: use that in ln. \exp_after:wN \__fp_fixed_mul_after:wwn \int_use:N \__int_eval:w \c__fp_leading_shift_int \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int #1#2*23025 - #1 #3 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int #1 #2*8509 - #1 #4 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int #1 #2*2994 - #1 #5 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int #1 #2*0456 - #1 #6 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_trailing_shift_int #1 #2*8401 - #1 #7 #1 ( #2*7991 - #8 ) / 1 0000 ; ; } \cs_new:Npn \__fp_pow_B:wwN #1#2#3#4#5#6; #7; { \if_int_compare:w #7 < \c_zero \exp_after:wN \__fp_pow_C_neg:w \__int_value:w - \else: \if_int_compare:w #7 < 22 \exp_stop_f: \exp_after:wN \__fp_pow_C_pos:w \__int_value:w \else: \exp_after:wN \__fp_pow_C_overflow:w \__int_value:w \fi: \fi: #7 \exp_after:wN ; \int_use:N \__int_eval:w 10 0000 + #1 \__int_eval_end: #2#3#4#5#6 0000 0000 0000 0000 0000 0000 ; %^^A todo: how many 0? } \cs_new:Npn \__fp_pow_C_overflow:w #1; #2; #3 { + \c_two * \c__fp_max_exponent_int \exp_after:wN \__fp_fixed_continue:wn \c__fp_one_fixed_tl ; } \cs_new:Npn \__fp_pow_C_neg:w #1 ; 1 { \exp_after:wN \exp_after:wN \exp_after:wN \__fp_pow_C_pack:w \prg_replicate:nn {#1} {0} } \cs_new:Npn \__fp_pow_C_pos:w #1; 1 { \__fp_pow_C_pos_loop:wN #1; } \cs_new:Npn \__fp_pow_C_pos_loop:wN #1; #2 { \if_meaning:w 0 #1 \exp_after:wN \__fp_pow_C_pack:w \exp_after:wN #2 \else: \if_meaning:w 0 #2 \exp_after:wN \__fp_pow_C_pos_loop:wN \__int_value:w \else: \exp_after:wN \__fp_pow_C_overflow:w \__int_value:w \fi: \__int_eval:w #1 - \c_one \exp_after:wN ; \fi: } \cs_new:Npn \__fp_pow_C_pack:w { \exp_after:wN \__fp_exp_large_v:wN \c__fp_one_fixed_tl ; } \cs_new:Npn \__fp_pow_neg:www \s__fp \__fp_chk:w #1#2; #3; #4; { \if_case:w \__fp_pow_neg_case:w #4 ; \exp_after:wN \__fp_pow_neg_aux:wNN \or: \if_int_compare:w \__int_eval:w #1 / \c_two = \c_one \__fp_invalid_operation_o:Nww ^ #3; #4; \tex_romannumeral:D -`0 \exp_after:wN \exp_after:wN \exp_after:wN \__fp_use_none_until_s:w \fi: \fi: \__fp_exp_after_o:w \s__fp \__fp_chk:w #1#2; } \cs_new:Npn \__fp_pow_neg_aux:wNN #1 \s__fp \__fp_chk:w #2#3 { \exp_after:wN \__fp_exp_after_o:w \exp_after:wN \s__fp \exp_after:wN \__fp_chk:w \exp_after:wN #2 \int_use:N \__int_eval:w \c_two - #3 \__int_eval_end: } \cs_new:Npn \__fp_pow_neg_case:w \s__fp \__fp_chk:w #1#2#3; { \if_case:w #1 \exp_stop_f: \c_minus_one \or: \__fp_pow_neg_case_aux:nnnnn #3 \else: \c_one \fi: } \cs_new:Npn \__fp_pow_neg_case_aux:nnnnn #1#2#3#4#5 { \if_int_compare:w #1 > \c_eight \if_int_compare:w #1 > \c_sixteen \c_minus_one \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_pow_neg_case_aux:NNNNNNNNw \prg_replicate:nn { \c_sixteen - #1 } { 0 } #4#5 ; \fi: \else: \if_int_compare:w #1 > \c_zero \if_int_compare:w #4#5 = \c_zero \exp_after:wN \exp_after:wN \exp_after:wN \__fp_pow_neg_case_aux:NNNNNNNNw \prg_replicate:nn { \c_eight - #1 } { 0 } #2#3 ; \else: \c_one \fi: \else: \c_one \fi: \fi: } \cs_new:Npn \__fp_pow_neg_case_aux:NNNNNNNNw #1#2#3#4#5#6#7#8#9; { \if_int_compare:w 0 #9 = \c_zero \if_int_odd:w #8 \exp_stop_f: \c_zero \else: \c_minus_one \fi: \else: \c_one \fi: } %% File: l3fp-trig.dtx Copyright (C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new:Npn \__fp_sin_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_case:w #2 \exp_stop_f: \__fp_case_return_same_o:w \or: \__fp_case_use:nw { \__fp_trig:NNNNNwn #1 \__fp_sin_series_o:NNwwww \__fp_ep_to_float:wwN #3 \c_zero } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { sin } { sind } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3 #4; } \cs_new:Npn \__fp_cos_o:w #1 \s__fp \__fp_chk:w #2#3; @ { \if_case:w #2 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: \__fp_case_use:nw { \__fp_trig:NNNNNwn #1 \__fp_sin_series_o:NNwwww \__fp_ep_to_float:wwN 0 \c_two } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { cos } { cosd } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3; } \cs_new:Npn \__fp_csc_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_case:w #2 \exp_stop_f: \__fp_cot_zero_o:Nfw #3 { #1 { csc } { cscd } } \or: \__fp_case_use:nw { \__fp_trig:NNNNNwn #1 \__fp_sin_series_o:NNwwww \__fp_ep_inv_to_float:wwN #3 \c_zero } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { csc } { cscd } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3 #4; } \cs_new:Npn \__fp_sec_o:w #1 \s__fp \__fp_chk:w #2#3; @ { \if_case:w #2 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: \__fp_case_use:nw { \__fp_trig:NNNNNwn #1 \__fp_sin_series_o:NNwwww \__fp_ep_inv_to_float:wwN 0 \c_two } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { sec } { secd } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3; } \cs_new:Npn \__fp_tan_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_case:w #2 \exp_stop_f: \__fp_case_return_same_o:w \or: \__fp_case_use:nw { \__fp_trig:NNNNNwn #1 \__fp_tan_series_o:NNwwww 0 #3 \c_one } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { tan } { tand } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3 #4; } \cs_new:Npn \__fp_cot_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_case:w #2 \exp_stop_f: \__fp_cot_zero_o:Nfw #3 { #1 { cot } { cotd } } \or: \__fp_case_use:nw { \__fp_trig:NNNNNwn #1 \__fp_tan_series_o:NNwwww 2 #3 \c_three } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { cot } { cotd } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3 #4; } \cs_new:Npn \__fp_cot_zero_o:Nfw #1#2#3 \fi: { \fi: \token_if_eq_meaning:NNTF 0 #1 { \exp_args:NNf \__fp_division_by_zero_o:Nnw \c_inf_fp } { \exp_args:NNf \__fp_division_by_zero_o:Nnw \c_minus_inf_fp } {#2} } \cs_new:Npn \__fp_trig:NNNNNwn #1#2#3#4#5 \s__fp \__fp_chk:w 1#6#7#8; { \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 \int_use:N \__int_eval:w #5 \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \if_int_compare:w #7 > #1 \c_zero \c_one #1 \__fp_trig_large:ww \__fp_trigd_large:ww \else: #1 \__fp_trig_small:ww \__fp_trigd_small:ww \fi: #7,#8{0000}{0000}; } \cs_new:Npn \__fp_trig_small:ww #1,#2; { \__fp_ep_to_fixed:wwn #1,#2; . #1,#2; } \cs_new:Npn \__fp_trigd_small:ww #1,#2; { \__fp_ep_mul_raw:wwwwN -1,{1745}{3292}{5199}{4329}{5769}{2369}; #1,#2; \__fp_trig_small:ww } \cs_new:Npn \__fp_trigd_large:ww #1, #2#3#4#5#6#7; { \exp_after:wN \__fp_pack_eight:wNNNNNNNN \exp_after:wN \__fp_pack_eight:wNNNNNNNN \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_trigd_large_auxi:nnnnwNNNN \exp_after:wN ; \tex_romannumeral:D -`0 \prg_replicate:nn { \int_max:nn { 22 - #1 } { 0 } } { 0 } #2#3#4#5#6#7 0000 0000 0000 ! } \cs_new:Npn \__fp_trigd_large_auxi:nnnnwNNNN #1#2#3#4#5; #6#7#8#9 { \exp_after:wN \__fp_trigd_large_auxii:wNw \int_use:N \__int_eval:w #1 + #2 - (#1 + #2 - \c_four) / \c_nine * \c_nine \__int_eval_end: #3; #4; #5{#6#7#8#9}; } \cs_new:Npn \__fp_trigd_large_auxii:wNw #1; #2#3; { + (#1#2 - \c_four) / \c_nine * \c_two \exp_after:wN \__fp_trigd_large_auxiii:www \int_use:N \__int_eval:w #1#2 - (#1#2 - \c_four) / \c_nine * \c_nine \__int_eval_end: #3 ; } \cs_new:Npn \__fp_trigd_large_auxiii:www #1; #2; #3! { \if_int_compare:w #1 < 4500 \exp_stop_f: \exp_after:wN \__fp_use_i_until_s:nw \exp_after:wN \__fp_fixed_continue:wn \else: + \c_one \fi: \__fp_fixed_sub:wwn {9000}{0000}{0000}{0000}{0000}{0000}; {#1}#2{0000}{0000}; { \__fp_trigd_small:ww 2, } } \cs_new_nopar:Npx \__fp_trig_inverse_two_pi: { \exp_not:n { \exp_after:wN \use_none:n \token_to_str:N } \cs:w , , ! 0000000000000000159154943091895335768883763372514362034459645740 ~ 4564487476673440588967976342265350901138027662530859560728427267 ~ 5795803689291184611457865287796741073169983922923996693740907757 ~ 3077746396925307688717392896217397661693362390241723629011832380 ~ 1142226997557159404618900869026739561204894109369378440855287230 ~ 9994644340024867234773945961089832309678307490616698646280469944 ~ 8652187881574786566964241038995874139348609983868099199962442875 ~ 5851711788584311175187671605465475369880097394603647593337680593 ~ 0249449663530532715677550322032477781639716602294674811959816584 ~ 0606016803035998133911987498832786654435279755070016240677564388 ~ 8495713108801221993761476813777647378906330680464579784817613124 ~ 2731406996077502450029775985708905690279678513152521001631774602 ~ 0924811606240561456203146484089248459191435211575407556200871526 ~ 6068022171591407574745827225977462853998751553293908139817724093 ~ 5825479707332871904069997590765770784934703935898280871734256403 ~ 6689511662545705943327631268650026122717971153211259950438667945 ~ 0376255608363171169525975812822494162333431451061235368785631136 ~ 3669216714206974696012925057833605311960859450983955671870995474 ~ 6510431623815517580839442979970999505254387566129445883306846050 ~ 7852915151410404892988506388160776196993073410389995786918905980 ~ 9373777206187543222718930136625526123878038753888110681406765434 ~ 0828278526933426799556070790386060352738996245125995749276297023 ~ 5940955843011648296411855777124057544494570217897697924094903272 ~ 9477021664960356531815354400384068987471769158876319096650696440 ~ 4776970687683656778104779795450353395758301881838687937766124814 ~ 9530599655802190835987510351271290432315804987196868777594656634 ~ 6221034204440855497850379273869429353661937782928735937843470323 ~ 0237145837923557118636341929460183182291964165008783079331353497 ~ 7909974586492902674506098936890945883050337030538054731232158094 ~ 3197676032283131418980974982243833517435698984750103950068388003 ~ 9786723599608024002739010874954854787923568261139948903268997427 ~ 0834961149208289037767847430355045684560836714793084567233270354 ~ 8539255620208683932409956221175331839402097079357077496549880868 ~ 6066360968661967037474542102831219251846224834991161149566556037 ~ 9696761399312829960776082779901007830360023382729879085402387615 ~ 5744543092601191005433799838904654921248295160707285300522721023 ~ 6017523313173179759311050328155109373913639645305792607180083617 ~ 9548767246459804739772924481092009371257869183328958862839904358 ~ 6866663975673445140950363732719174311388066383072592302759734506 ~ 0548212778037065337783032170987734966568490800326988506741791464 ~ 6835082816168533143361607309951498531198197337584442098416559541 ~ 5225064339431286444038388356150879771645017064706751877456059160 ~ 8716857857939226234756331711132998655941596890719850688744230057 ~ 5191977056900382183925622033874235362568083541565172971088117217 ~ 9593683256488518749974870855311659830610139214454460161488452770 ~ 2511411070248521739745103866736403872860099674893173561812071174 ~ 0478899368886556923078485023057057144063638632023685201074100574 ~ 8592281115721968003978247595300166958522123034641877365043546764 ~ 6456565971901123084767099309708591283646669191776938791433315566 ~ 5066981321641521008957117286238426070678451760111345080069947684 ~ 2235698962488051577598095339708085475059753626564903439445420581 ~ 7886435683042000315095594743439252544850674914290864751442303321 ~ 3324569511634945677539394240360905438335528292434220349484366151 ~ 4663228602477666660495314065734357553014090827988091478669343492 ~ 2737602634997829957018161964321233140475762897484082891174097478 ~ 2637899181699939487497715198981872666294601830539583275209236350 ~ 6853889228468247259972528300766856937583659722919824429747406163 ~ 8183113958306744348516928597383237392662402434501997809940402189 ~ 6134834273613676449913827154166063424829363741850612261086132119 ~ 9863346284709941839942742955915628333990480382117501161211667205 ~ 1912579303552929241134403116134112495318385926958490443846807849 ~ 0973982808855297045153053991400988698840883654836652224668624087 ~ 2540140400911787421220452307533473972538149403884190586842311594 ~ 6322744339066125162393106283195323883392131534556381511752035108 ~ 7459558201123754359768155340187407394340363397803881721004531691 ~ 8295194879591767395417787924352761740724605939160273228287946819 ~ 3649128949714953432552723591659298072479985806126900733218844526 ~ 7943350455801952492566306204876616134365339920287545208555344144 ~ 0990512982727454659118132223284051166615650709837557433729548631 ~ 2041121716380915606161165732000083306114606181280326258695951602 ~ 4632166138576614804719932707771316441201594960110632830520759583 ~ 4850305079095584982982186740289838551383239570208076397550429225 ~ 9847647071016426974384504309165864528360324933604354657237557916 ~ 1366324120457809969715663402215880545794313282780055246132088901 ~ 8742121092448910410052154968097113720754005710963406643135745439 ~ 9159769435788920793425617783022237011486424925239248728713132021 ~ 7667360756645598272609574156602343787436291321097485897150713073 ~ 9104072643541417970572226547980381512759579124002534468048220261 ~ 7342299001020483062463033796474678190501811830375153802879523433 ~ 4195502135689770912905614317878792086205744999257897569018492103 ~ 2420647138519113881475640209760554895793785141404145305151583964 ~ 2823265406020603311891586570272086250269916393751527887360608114 ~ 5569484210322407772727421651364234366992716340309405307480652685 ~ 0930165892136921414312937134106157153714062039784761842650297807 ~ 8606266969960809184223476335047746719017450451446166382846208240 ~ 8673595102371302904443779408535034454426334130626307459513830310 ~ 2293146934466832851766328241515210179422644395718121717021756492 ~ 1964449396532222187658488244511909401340504432139858628621083179 ~ 3939608443898019147873897723310286310131486955212620518278063494 ~ 5711866277825659883100535155231665984394090221806314454521212978 ~ 9734471488741258268223860236027109981191520568823472398358013366 ~ 0683786328867928619732367253606685216856320119489780733958419190 ~ 6659583867852941241871821727987506103946064819585745620060892122 ~ 8416394373846549589932028481236433466119707324309545859073361878 ~ 6290631850165106267576851216357588696307451999220010776676830946 ~ 9814975622682434793671310841210219520899481912444048751171059184 ~ 4139907889455775184621619041530934543802808938628073237578615267 ~ 7971143323241969857805637630180884386640607175368321362629671224 ~ 2609428540110963218262765120117022552929289655594608204938409069 ~ 0760692003954646191640021567336017909631872891998634341086903200 ~ 5796637103128612356988817640364252540837098108148351903121318624 ~ 7228181050845123690190646632235938872454630737272808789830041018 ~ 9485913673742589418124056729191238003306344998219631580386381054 ~ 2457893450084553280313511884341007373060595654437362488771292628 ~ 9807423539074061786905784443105274262641767830058221486462289361 ~ 9296692992033046693328438158053564864073184440599549689353773183 ~ 6726613130108623588021288043289344562140479789454233736058506327 ~ 0439981932635916687341943656783901281912202816229500333012236091 ~ 8587559201959081224153679499095448881099758919890811581163538891 ~ 6339402923722049848375224236209100834097566791710084167957022331 ~ 7897107102928884897013099533995424415335060625843921452433864640 ~ 3432440657317477553405404481006177612569084746461432976543900008 ~ 3826521145210162366431119798731902751191441213616962045693602633 ~ 6102355962140467029012156796418735746835873172331004745963339773 ~ 2477044918885134415363760091537564267438450166221393719306748706 ~ 2881595464819775192207710236743289062690709117919412776212245117 ~ 2354677115640433357720616661564674474627305622913332030953340551 ~ 3841718194605321501426328000879551813296754972846701883657425342 ~ 5016994231069156343106626043412205213831587971115075454063290657 ~ 0248488648697402872037259869281149360627403842332874942332178578 ~ 7750735571857043787379693402336902911446961448649769719434527467 ~ 4429603089437192540526658890710662062575509930379976658367936112 ~ 8137451104971506153783743579555867972129358764463093757203221320 ~ 2460565661129971310275869112846043251843432691552928458573495971 ~ 5042565399302112184947232132380516549802909919676815118022483192 ~ 5127372199792134331067642187484426215985121676396779352982985195 ~ 8545392106957880586853123277545433229161989053189053725391582222 ~ 9232597278133427818256064882333760719681014481453198336237910767 ~ 1255017528826351836492103572587410356573894694875444694018175923 ~ 0609370828146501857425324969212764624247832210765473750568198834 ~ 5641035458027261252285503154325039591848918982630498759115406321 ~ 0354263890012837426155187877318375862355175378506956599570028011 ~ 5841258870150030170259167463020842412449128392380525772514737141 ~ 2310230172563968305553583262840383638157686828464330456805994018 ~ 7001071952092970177990583216417579868116586547147748964716547948 ~ 8312140431836079844314055731179349677763739898930227765607058530 ~ 4083747752640947435070395214524701683884070908706147194437225650 ~ 2823145872995869738316897126851939042297110721350756978037262545 ~ 8141095038270388987364516284820180468288205829135339013835649144 ~ 3004015706509887926715417450706686888783438055583501196745862340 ~ 8059532724727843829259395771584036885940989939255241688378793572 ~ 7967951654076673927031256418760962190243046993485989199060012977 ~ 7469214532970421677817261517850653008552559997940209969455431545 ~ 2745856704403686680428648404512881182309793496962721836492935516 ~ 2029872469583299481932978335803459023227052612542114437084359584 ~ 9443383638388317751841160881711251279233374577219339820819005406 ~ 3292937775306906607415304997682647124407768817248673421685881509 ~ 9133422075930947173855159340808957124410634720893194912880783576 ~ 3115829400549708918023366596077070927599010527028150868897828549 ~ 4340372642729262103487013992868853550062061514343078665396085995 ~ 0058714939141652065302070085265624074703660736605333805263766757 ~ 2018839497277047222153633851135483463624619855425993871933367482 ~ 0422097449956672702505446423243957506869591330193746919142980999 ~ 3424230550172665212092414559625960554427590951996824313084279693 ~ 7113207021049823238195747175985519501864630940297594363194450091 ~ 9150616049228764323192129703446093584259267276386814363309856853 ~ 2786024332141052330760658841495858718197071242995959226781172796 ~ 4438853796763139274314227953114500064922126500133268623021550837 \cs_end: } \cs_new:Npn \__fp_trig_large:ww #1, #2#3#4#5#6; { \exp_after:wN \__fp_trig_large_auxi:wwwwww \int_use:N \__int_eval:w (#1 - 32) / 64 \exp_after:wN , \int_use:N \__int_eval:w (#1 - 4) / 8 \exp_after:wN , \__int_value:w #1 \__fp_trig_inverse_two_pi: ; {#2}{#3}{#4}{#5} ; } \cs_new:Npn \__fp_trig_large_auxi:wwwwww #1, #2, #3, #4! { \prg_replicate:nn {#1} { \__fp_trig_large_auxii:ww } \prg_replicate:nn { #2 - #1 * \c_eight } { \__fp_trig_large_auxiii:wNNNNNNNN } \prg_replicate:nn { #3 - #2 * \c_eight } { \__fp_trig_large_auxiv:wN } \prg_replicate:nn { \c_eight } { \__fp_pack_twice_four:wNNNNNNNN } \__fp_trig_large_auxv:www ; } \cs_new:Npn \__fp_trig_large_auxii:ww #1; #2 ~ { #1; } \cs_new:Npn \__fp_trig_large_auxiii:wNNNNNNNN #1; #2#3#4#5#6#7#8#9 { #1; } \cs_new:Npn \__fp_trig_large_auxiv:wN #1; #2 { #1; } \cs_new:Npn \__fp_trig_large_auxv:www #1; #2; #3; { \exp_after:wN \__fp_use_i_until_s:nw \exp_after:wN \__fp_trig_large_auxvii:w \int_use:N \__int_eval:w \c__fp_leading_shift_int \prg_replicate:nn { \c_thirteen } { \__fp_trig_large_auxvi:wnnnnnnnn } + \c__fp_trailing_shift_int - \c__fp_middle_shift_int \__fp_use_i_until_s:nw ; #3 #1 ; ; } \cs_new:Npn \__fp_trig_large_auxvi:wnnnnnnnn #1; #2#3#4#5#6#7#8#9 { \exp_after:wN \__fp_trig_large_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #2*#9 + #3*#8 + #4*#7 + #5*#6 #1; {#2}{#3}{#4}{#5} {#7}{#8}{#9} } \cs_new:Npn \__fp_trig_large_pack:NNNNNw #1#2#3#4#5#6; { + #1#2#3#4#5 ; #6 } \cs_new:Npn \__fp_trig_large_auxvii:w #1#2#3 { \exp_after:wN \__fp_trig_large_auxviii:ww \int_use:N \__int_eval:w (#1#2#3 - 62) / 125 ; #1#2#3 } \cs_new:Npn \__fp_trig_large_auxviii:ww #1; { + #1 \if_int_odd:w #1 \exp_stop_f: \exp_after:wN \__fp_trig_large_auxix:Nw \exp_after:wN - \else: \exp_after:wN \__fp_trig_large_auxix:Nw \exp_after:wN + \fi: } \cs_new_nopar:Npn \__fp_trig_large_auxix:Nw { \exp_after:wN \__fp_use_i_until_s:nw \exp_after:wN \__fp_trig_large_auxxi:w \int_use:N \__int_eval:w \c__fp_leading_shift_int \prg_replicate:nn { \c_thirteen } { \__fp_trig_large_auxx:wNNNNN } + \c__fp_trailing_shift_int - \c__fp_middle_shift_int ; } \cs_new:Npn \__fp_trig_large_auxx:wNNNNN #1; #2 #3#4#5#6 { \exp_after:wN \__fp_trig_large_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int #2 \c_eight * #3#4#5#6 #1; #2 } \cs_new:Npn \__fp_trig_large_auxxi:w #1; { \exp_after:wN \__fp_ep_mul_raw:wwwwN \int_use:N \__int_eval:w \c_zero \__fp_ep_to_ep_loop:N #1 ; ; ! 0,{7853}{9816}{3397}{4483}{0961}{5661}; \__fp_trig_small:ww } \cs_new:Npn \__fp_sin_series_o:NNwwww #1#2#3. #4; { \__fp_fixed_mul:wwn #4; #4; { \exp_after:wN \__fp_sin_series_aux_o:NNnwww \exp_after:wN #1 \__int_value:w \if_int_odd:w \__int_eval:w ( #3 + \c_two ) / \c_four \__int_eval_end: #2 \else: \if_meaning:w #2 0 2 \else: 0 \fi: \fi: {#3} } } \cs_new:Npn \__fp_sin_series_aux_o:NNnwww #1#2#3 #4; #5,#6; { \if_int_odd:w \__int_eval:w #3 / \c_two \__int_eval_end: \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: { % 1/18! \__fp_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0001}{5619}{2070}; #4; {0000}{0000}{0000}{0477}{9477}{3324}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0000}{0011}{4707}{4559}{7730}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0000}{2087}{6756}{9878}{6810}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0027}{5573}{1922}{3985}{8907}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{2480}{1587}{3015}{8730}{1587}; \__fp_fixed_mul_sub_back:wwwn #4; {0013}{8888}{8888}{8888}{8888}{8889}; \__fp_fixed_mul_sub_back:wwwn #4; {0416}{6666}{6666}{6666}{6666}{6667}; \__fp_fixed_mul_sub_back:wwwn #4; {5000}{0000}{0000}{0000}{0000}{0000}; \__fp_fixed_mul_sub_back:wwwn #4;{10000}{0000}{0000}{0000}{0000}{0000}; { \__fp_fixed_continue:wn 0, } } { % 1/17! \__fp_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0028}{1145}{7254}; #4; {0000}{0000}{0000}{7647}{1637}{3182}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0000}{0160}{5904}{3836}{8216}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0002}{5052}{1083}{8544}{1719}; \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0275}{5731}{9223}{9858}{9065}; \__fp_fixed_mul_sub_back:wwwn #4; {0001}{9841}{2698}{4126}{9841}{2698}; \__fp_fixed_mul_sub_back:wwwn #4; {0083}{3333}{3333}{3333}{3333}{3333}; \__fp_fixed_mul_sub_back:wwwn #4; {1666}{6666}{6666}{6666}{6666}{6667}; \__fp_fixed_mul_sub_back:wwwn #4;{10000}{0000}{0000}{0000}{0000}{0000}; { \__fp_ep_mul:wwwwn 0, } #5,#6; } { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #2 \int_use:N \__int_eval:w #1 } #2 } \cs_new:Npn \__fp_tan_series_o:NNwwww #1#2#3. #4; { \__fp_fixed_mul:wwn #4; #4; { \exp_after:wN \__fp_tan_series_aux_o:Nnwww \__int_value:w \if_int_odd:w \__int_eval:w #3 / \c_two \__int_eval_end: \exp_after:wN \reverse_if:N \fi: \if_meaning:w #1#2 2 \else: 0 \fi: {#3} } } \cs_new:Npn \__fp_tan_series_aux_o:Nnwww #1 #2 #3; #4,#5; { \__fp_fixed_mul_sub_back:wwwn {0000}{0000}{1527}{3493}{0856}{7059}; #3; {0000}{0159}{6080}{0274}{5257}{6472}; \__fp_fixed_mul_sub_back:wwwn #3; {0002}{4571}{2320}{0157}{2558}{8481}; \__fp_fixed_mul_sub_back:wwwn #3; {0115}{5830}{7533}{5397}{3168}{2147}; \__fp_fixed_mul_sub_back:wwwn #3; {1929}{8245}{6140}{3508}{7719}{2982}; \__fp_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; { \__fp_ep_mul:wwwwn 0, } #4,#5; { \__fp_fixed_mul_sub_back:wwwn {0000}{0007}{0258}{0681}{9408}{4706}; #3; {0000}{2343}{7175}{1399}{6151}{7670}; \__fp_fixed_mul_sub_back:wwwn #3; {0019}{2638}{4588}{9232}{8861}{3691}; \__fp_fixed_mul_sub_back:wwwn #3; {0536}{6357}{0691}{4344}{6852}{4252}; \__fp_fixed_mul_sub_back:wwwn #3; {5263}{1578}{9473}{6842}{1052}{6315}; \__fp_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; { \reverse_if:N \if_int_odd:w \__int_eval:w (#2 - \c_one) / \c_two \__int_eval_end: \exp_after:wN \__fp_reverse_args:Nww \fi: \__fp_ep_div:wwwwn 0, } } { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w \__fp_ep_to_float:wwN } #1 } \cs_new_nopar:Npn \__fp_atan_o:Nw { \__fp_atan_dispatch_o:NNnNw \__fp_acotii_o:Nww \__fp_atanii_o:Nww { atan } } \cs_new_nopar:Npn \__fp_acot_o:Nw { \__fp_atan_dispatch_o:NNnNw \__fp_atanii_o:Nww \__fp_acotii_o:Nww { acot } } \cs_new:Npn \__fp_atan_dispatch_o:NNnNw #1#2#3#4#5@ { \if_case:w \__int_eval:w \__fp_array_count:n {#5} - \c_one \__int_eval_end: \exp_after:wN #1 \exp_after:wN #4 \c_one_fp #5 \tex_romannumeral:D \or: #2 #4 #5 \tex_romannumeral:D \else: \__msg_kernel_expandable_error:nnnnn { kernel } { fp-num-args } { #3() } { 1 } { 2 } \exp_after:wN \c_nan_fp \tex_romannumeral:D \fi: \exp_after:wN \c_zero } \cs_new:Npn \__fp_atanii_o:Nww #1 \s__fp \__fp_chk:w #2#3#4; \s__fp \__fp_chk:w #5 { \if_meaning:w 3 #2 \__fp_case_return_i_o:ww \fi: \if_meaning:w 3 #5 \__fp_case_return_ii_o:ww \fi: \if_case:w \if_meaning:w #2 #5 \if_meaning:w 1 #2 \c_ten \else: \c_zero \fi: \else: \if_int_compare:w #2 > #5 \c_one \else: \c_two \fi: \fi: \__fp_case_return:nw { \__fp_atan_inf_o:NNNw #1 #3 \c_two } \or: \__fp_case_return:nw { \__fp_atan_inf_o:NNNw #1 #3 \c_four } \or: \__fp_case_return:nw { \__fp_atan_inf_o:NNNw #1 #3 \c_zero } \fi: \__fp_atan_normal_o:NNnwNnw #1 \s__fp \__fp_chk:w #2#3#4; \s__fp \__fp_chk:w #5 } \cs_new:Npn \__fp_acotii_o:Nww #1#2; #3; { \__fp_atanii_o:Nww #1#3; #2; } \cs_new:Npn \__fp_atan_inf_o:NNNw #1#2#3 \s__fp \__fp_chk:w #4#5#6; { \exp_after:wN \__fp_atan_combine_o:NwwwwwN \exp_after:wN #2 \int_use:N \__int_eval:w \if_meaning:w 2 #5 \c_seven - \fi: #3 \exp_after:wN ; \c__fp_one_fixed_tl ; {0000}{0000}{0000}{0000}{0000}{0000}; 0,{0000}{0000}{0000}{0000}{0000}{0000}; #1 } \cs_new_protected:Npn \__fp_atan_normal_o:NNnwNnw #1 \s__fp \__fp_chk:w 1#2#3#4; \s__fp \__fp_chk:w 1#5#6#7; { \__fp_atan_test_o:NwwNwwN #2 #3, #4{0000}{0000}; #5 #6, #7{0000}{0000}; #1 } \cs_new:Npn \__fp_atan_test_o:NwwNwwN #1#2,#3; #4#5,#6; { \exp_after:wN \__fp_atan_combine_o:NwwwwwN \exp_after:wN #1 \int_use:N \__int_eval:w \if_meaning:w 2 #4 \c_seven - \__int_eval:w \fi: \if_int_compare:w \__fp_ep_compare:wwww #2,#3; #5,#6; > \c_zero \c_three - \exp_after:wN \__fp_reverse_args:Nww \fi: \__fp_atan_div:wnwwnw #2,#3; #5,#6; } \cs_new:Npn \__fp_atan_div:wnwwnw #1,#2#3; #4,#5#6; { \if_int_compare:w \__int_eval:w 41421 * #5 < #2 000 \if_case:w \__int_eval:w #4 - #1 \__int_eval_end: 00 \or: 0 \fi: \exp_stop_f: \exp_after:wN \__fp_atan_near:wwwn \fi: \c_zero \__fp_ep_div:wwwwn #1,{#2}#3; #4,{#5}#6; \__fp_atan_auxi:ww } \cs_new:Npn \__fp_atan_near:wwwn \c_zero \__fp_ep_div:wwwwn #1,#2; #3, { \c_one \__fp_ep_to_fixed:wwn #1 - #3, #2; \__fp_atan_near_aux:wwn } \cs_new:Npn \__fp_atan_near_aux:wwn #1; #2; { \__fp_fixed_add:wwn #1; #2; { \__fp_fixed_sub:wwn #2; #1; { \__fp_ep_div:wwwwn 0, } 0, } } \cs_new:Npn \__fp_atan_auxi:ww #1,#2; { \__fp_ep_to_fixed:wwn #1,#2; \__fp_atan_auxii:w #1,#2; } \cs_new:Npn \__fp_atan_auxii:w #1; { \__fp_fixed_mul:wwn #1; #1; { \__fp_atan_Taylor_loop:www 39 ; {0000}{0000}{0000}{0000}{0000}{0000} ; } ! #1; } \cs_new:Npn \__fp_atan_Taylor_loop:www #1; #2; #3; { \if_int_compare:w #1 = \c_minus_one \__fp_atan_Taylor_break:w \fi: \exp_after:wN \__fp_fixed_div_int:wwN \c__fp_one_fixed_tl ; #1; \__fp_rrot:www \__fp_fixed_mul_sub_back:wwwn #2; #3; { \exp_after:wN \__fp_atan_Taylor_loop:www \int_use:N \__int_eval:w #1 - \c_two ; } #3; } \cs_new:Npn \__fp_atan_Taylor_break:w \fi: #1 \__fp_fixed_mul_sub_back:wwwn #2; #3 ! { \fi: ; #2 ; } \cs_new:Npn \__fp_atan_combine_o:NwwwwwN #1 #2; #3; #4; #5,#6; #7 { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w \if_meaning:w 0 #2 \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: { #5 \__fp_fixed_mul:wwn #3; #6; } { \__fp_fixed_mul:wwn #3; #4; { \exp_after:wN \__fp_atan_combine_aux:ww \int_use:N \__int_eval:w #2 / \c_two ; #2; } } { #7 \__fp_fixed_to_float:wN \__fp_fixed_to_float_rad:wN } #1 } \cs_new:Npn \__fp_atan_combine_aux:ww #1; #2; { \__fp_fixed_mul_short:wwn {7853}{9816}{3397}{4483}{0961}{5661}; {#1}{0000}{0000}; { \if_int_odd:w #2 \exp_stop_f: \exp_after:wN \__fp_fixed_sub:wwn \else: \exp_after:wN \__fp_fixed_add:wwn \fi: } } \cs_new:Npn \__fp_asin_o:w #1 \s__fp \__fp_chk:w #2#3; @ { \if_case:w #2 \exp_stop_f: \__fp_case_return_same_o:w \or: \__fp_case_use:nw { \__fp_asin_normal_o:NfwNnnnnw #1 { #1 { asin } { asind } } } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { asin } { asind } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3; } \cs_new:Npn \__fp_acos_o:w #1 \s__fp \__fp_chk:w #2#3; @ { \if_case:w #2 \exp_stop_f: \__fp_case_use:nw { \__fp_atan_inf_o:NNNw #1 0 \c_four } \or: \__fp_case_use:nw { \__fp_asin_normal_o:NfwNnnnnw #1 { #1 { acos } { acosd } } \__fp_reverse_args:Nww } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { acos } { acosd } } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3; } \cs_new:Npn \__fp_asin_normal_o:NfwNnnnnw #1#2#3 \s__fp \__fp_chk:w 1#4#5#6#7#8#9; { \if_int_compare:w #5 < \c_one \exp_after:wN \__fp_use_none_until_s:w \fi: \if_int_compare:w \__int_eval:w #5 + #6#7 + #8#9 = 1000 0001 ~ \exp_after:wN \__fp_use_none_until_s:w \fi: \__fp_use_i:ww \__fp_invalid_operation_o:fw {#2} \s__fp \__fp_chk:w 1#4{#5}{#6}{#7}{#8}{#9}; \__fp_asin_auxi_o:NnNww #1 {#3} #4 #5,{#6}{#7}{#8}{#9}{0000}{0000}; } \cs_new:Npn \__fp_asin_auxi_o:NnNww #1#2#3#4,#5; { \__fp_ep_to_fixed:wwn #4,#5; \__fp_asin_isqrt:wn \__fp_ep_mul:wwwwn #4,#5; \__fp_ep_to_ep:wwN \__fp_fixed_continue:wn { #2 \__fp_atan_test_o:NwwNwwN #3 } 0 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1 } \cs_new:Npn \__fp_asin_isqrt:wn #1; { \exp_after:wN \__fp_fixed_sub:wwn \c__fp_one_fixed_tl ; #1; { \__fp_fixed_add_one:wN #1; \__fp_fixed_continue:wn { \__fp_ep_mul:wwwwn 0, } 0, } \__fp_ep_isqrt:wwn } \cs_new:Npn \__fp_acsc_o:w #1 \s__fp \__fp_chk:w #2#3#4; @ { \if_case:w \if_meaning:w 2 #2 #3 \fi: #2 \exp_stop_f: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { acsc } { acscd } } } \or: \__fp_case_use:nw { \__fp_acsc_normal_o:NfwNnw #1 { #1 { acsc } { acscd } } } \or: \__fp_case_return_o:Nw \c_zero_fp \or: \__fp_case_return_same_o:w \else: \__fp_case_return_o:Nw \c_minus_zero_fp \fi: \s__fp \__fp_chk:w #2 #3 #4; } \cs_new:Npn \__fp_asec_o:w #1 \s__fp \__fp_chk:w #2#3; @ { \if_case:w #2 \exp_stop_f: \__fp_case_use:nw { \__fp_invalid_operation_o:fw { #1 { asec } { asecd } } } \or: \__fp_case_use:nw { \__fp_acsc_normal_o:NfwNnw #1 { #1 { asec } { asecd } } \__fp_reverse_args:Nww } \or: \__fp_case_use:nw { \__fp_atan_inf_o:NNNw #1 0 \c_four } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #2 #3; } \cs_new:Npn \__fp_acsc_normal_o:NfwNnw #1#2#3 \s__fp \__fp_chk:w 1#4#5#6; { \int_compare:nNnTF {#5} < \c_one { \__fp_invalid_operation_o:fw {#2} \s__fp \__fp_chk:w 1#4{#5}#6; } { \__fp_ep_div:wwwwn 1,{1000}{0000}{0000}{0000}{0000}{0000}; #5,#6{0000}{0000}; { \__fp_asin_auxi_o:NnNww #1 {#3} #4 } } } %% File: l3fp-convert.dtx Copyright(C) 2011-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new:Npn \__fp_trim_zeros:w #1 ; { \__fp_trim_zeros_loop:w #1 ; \__fp_trim_zeros_loop:w 0; \__fp_trim_zeros_dot:w .; \s__stop } \cs_new:Npn \__fp_trim_zeros_loop:w #1 0; #2 { #2 #1 ; #2 } \cs_new:Npn \__fp_trim_zeros_dot:w #1 .; { \__fp_trim_zeros_end:w #1 ; } \cs_new:Npn \__fp_trim_zeros_end:w #1 ; #2 \s__stop { #1 } \cs_new:Npn \fp_to_scientific:N #1 { \exp_after:wN \__fp_to_scientific_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_scientific:N { c } \cs_new_nopar:Npn \fp_to_scientific:n { \exp_after:wN \__fp_to_scientific_dispatch:w \tex_romannumeral:D -`0 \__fp_parse:n } \group_begin: \char_set_catcode_other:N E \tl_to_lowercase:n { \group_end: \cs_new:Npn \__fp_to_scientific_dispatch:w \s__fp \__fp_chk:w #1#2 { \if_meaning:w 2 #2 \exp_after:wN - \tex_romannumeral:D -`0 \fi: \if_case:w #1 \exp_stop_f: \__fp_case_return:nw { 0 } \or: \exp_after:wN \__fp_to_scientific_normal:wnnnnn \or: \__fp_case_use:nw { \__fp_invalid_operation:nnw { \exp_after:wN 1 \exp_after:wN E \int_use:N \c__fp_max_exponent_int } { fp_to_scientific } } \or: \__fp_case_use:nw { \__fp_invalid_operation:nnw { 0 } { fp_to_scientific } } \fi: \s__fp \__fp_chk:w #1 #2 } \cs_new:Npn \__fp_to_scientific_normal:wnnnnn \s__fp \__fp_chk:w 1 #1 #2 #3#4#5#6 ; { \if_int_compare:w #2 = \c_one \exp_after:wN \__fp_to_scientific_normal:wNw \else: \exp_after:wN \__fp_to_scientific_normal:wNw \exp_after:wN E \int_use:N \__int_eval:w #2 - \c_one \fi: ; #3 #4 #5 #6 ; } } \cs_new:Npn \__fp_to_scientific_normal:wNw #1 ; #2#3; { \__fp_trim_zeros:w #2.#3 ; #1 } \cs_new:Npn \fp_to_decimal:N #1 { \exp_after:wN \__fp_to_decimal_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_decimal:N { c } \cs_new_nopar:Npn \fp_to_decimal:n { \exp_after:wN \__fp_to_decimal_dispatch:w \tex_romannumeral:D -`0 \__fp_parse:n } \cs_new:Npn \__fp_to_decimal_dispatch:w \s__fp \__fp_chk:w #1#2 { \if_meaning:w 2 #2 \exp_after:wN - \tex_romannumeral:D -`0 \fi: \if_case:w #1 \exp_stop_f: \__fp_case_return:nw { 0 } \or: \exp_after:wN \__fp_to_decimal_normal:wnnnnn \or: \__fp_case_use:nw { \__fp_invalid_operation:nnw { \exp_after:wN \exp_after:wN \exp_after:wN 1 \prg_replicate:nn \c__fp_max_exponent_int 0 } { fp_to_decimal } } \or: \__fp_case_use:nw { \__fp_invalid_operation:nnw { 0 } { fp_to_decimal } } \fi: \s__fp \__fp_chk:w #1 #2 } \cs_new:Npn \__fp_to_decimal_normal:wnnnnn \s__fp \__fp_chk:w 1 #1 #2 #3#4#5#6 ; { \int_compare:nNnTF {#2} > \c_zero { \int_compare:nNnTF {#2} < \c_sixteen { \__fp_decimate:nNnnnn { \c_sixteen - #2 } \__fp_to_decimal_large:Nnnw } { \exp_after:wN \exp_after:wN \exp_after:wN \__fp_to_decimal_huge:wnnnn \prg_replicate:nn { #2 - \c_sixteen } { 0 } ; } {#3} {#4} {#5} {#6} } { \exp_after:wN \__fp_trim_zeros:w \exp_after:wN 0 \exp_after:wN . \tex_romannumeral:D -`0 \prg_replicate:nn { - #2 } { 0 } #3#4#5#6 ; } } \cs_new:Npn \__fp_to_decimal_large:Nnnw #1#2#3#4; { \exp_after:wN \__fp_trim_zeros:w \__int_value:w \if_int_compare:w #2 > \c_zero #2 \fi: \exp_stop_f: #3.#4 ; } \cs_new:Npn \__fp_to_decimal_huge:wnnnn #1; #2#3#4#5 { #2#3#4#5 #1 } \cs_new:Npn \fp_to_tl:N #1 { \exp_after:wN \__fp_to_tl_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_tl:N { c } \cs_new_nopar:Npn \fp_to_tl:n { \exp_after:wN \__fp_to_tl_dispatch:w \tex_romannumeral:D -`0 \__fp_parse:n } \cs_new:Npn \__fp_to_tl_dispatch:w \s__fp \__fp_chk:w #1#2 { \if_meaning:w 2 #2 \exp_after:wN - \tex_romannumeral:D -`0 \fi: \if_case:w #1 \exp_stop_f: \__fp_case_return:nw { 0 } \or: \exp_after:wN \__fp_to_tl_normal:nnnnn \or: \__fp_case_return:nw { \tl_to_str:n {inf} } \else: \__fp_case_return:nw { \tl_to_str:n {nan} } \fi: } \cs_new:Npn \__fp_to_tl_normal:nnnnn #1 { \if_int_compare:w #1 > \c_sixteen \exp_after:wN \__fp_to_scientific_normal:wnnnnn \else: \if_int_compare:w #1 < - \c_two \exp_after:wN \exp_after:wN \exp_after:wN \__fp_to_scientific_normal:wnnnnn \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_to_decimal_normal:wnnnnn \fi: \fi: \s__fp \__fp_chk:w 1 0 {#1} } \cs_new:Npx \fp_to_dim:N #1 { \exp_not:N \fp_to_decimal:N #1 \tl_to_str:n {pt} } \cs_generate_variant:Nn \fp_to_dim:N { c } \cs_new:Npx \fp_to_dim:n #1 { \exp_not:N \fp_to_decimal:n {#1} \tl_to_str:n {pt} } \cs_new:Npn \fp_to_int:N #1 { \exp_after:wN \__fp_to_int_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_int:N { c } \cs_new_nopar:Npn \fp_to_int:n { \exp_after:wN \__fp_to_int_dispatch:w \tex_romannumeral:D -`0 \__fp_parse:n } \cs_new:Npn \__fp_to_int_dispatch:w #1; { \exp_after:wN \__fp_to_decimal_dispatch:w \tex_romannumeral:D -`0 \__fp_round:Nwn \__fp_round_to_nearest:NNN #1; { 0 } } \cs_new:Npn \dim_to_fp:n #1 { \exp_after:wN \__fp_from_dim_test:ww \exp_after:wN 0 \exp_after:wN , \__int_value:w \etex_glueexpr:D #1 ; } \cs_new:Npn \__fp_from_dim_test:ww #1, #2 { \if_meaning:w 0 #2 \__fp_case_return:nw { \exp_after:wN \c_zero_fp } \else: \exp_after:wN \__fp_from_dim:wNw \int_use:N \__int_eval:w #1 - \c_four \if_meaning:w - #2 \exp_after:wN , \exp_after:wN 2 \__int_value:w \else: \exp_after:wN , \exp_after:wN 0 \__int_value:w #2 \fi: \fi: } \cs_new:Npn \__fp_from_dim:wNw #1,#2#3; { \__fp_pack_twice_four:wNNNNNNNN \__fp_from_dim:wNNnnnnnn ; #3 000 0000 00 {10}987654321; #2 {#1} } \cs_new:Npn \__fp_from_dim:wNNnnnnnn #1; #2#3#4#5#6#7#8#9 { \__fp_from_dim:wnnnnwNn #1 {#2#300} {0000} ; } \cs_new:Npn \__fp_from_dim:wnnnnwNn #1; #2#3#4#5#6; #7#8 { \__fp_mul_npos_o:Nww #7 \s__fp \__fp_chk:w 1 #7 {#5} #1 ; \s__fp \__fp_chk:w 1 0 {#8} {1525} {8789} {0625} {0000} ; \prg_do_nothing: } \cs_new_eq:NN \fp_use:N \fp_to_decimal:N \cs_generate_variant:Nn \fp_use:N { c } \cs_new_eq:NN \fp_eval:n \fp_to_decimal:n \cs_new:Npn \fp_abs:n #1 { \fp_to_decimal:n { abs \__fp_parse:n {#1} } } \cs_new:Npn \fp_max:nn #1#2 { \fp_to_decimal:n { max ( \__fp_parse:n {#1} , \__fp_parse:n {#2} ) } } \cs_new:Npn \fp_min:nn #1#2 { \fp_to_decimal:n { min ( \__fp_parse:n {#1} , \__fp_parse:n {#2} ) } } \cs_new:Npn \__fp_array_to_clist:n #1 { \tl_if_empty:nF {#1} { \__fp_expand:n { { \use_ii:nn } \__fp_array_to_clist_loop:Nw #1 { ? \__prg_break: } ; \__prg_break_point: } } } \cs_new:Npx \__fp_array_to_clist_loop:Nw #1#2; { \exp_not:N \use_none:n #1 \exp_not:N \exp_after:wN { \exp_not:N \exp_after:wN , \exp_not:N \exp_after:wN \c_space_tl \exp_not:N \tex_romannumeral:D -`0 \exp_not:N \__fp_to_tl_dispatch:w #1 #2 ; } \exp_not:N \__fp_array_to_clist_loop:Nw } %% %% File: l3fp-assign.dtx Copyright (C) 2011-2013 The LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% \cs_new_protected:Npn \fp_new:N #1 { \cs_new_eq:NN #1 \c_zero_fp } \cs_generate_variant:Nn \fp_new:N {c} \cs_new_protected:Npn \fp_set:Nn #1#2 { \tl_set:Nx #1 { \exp_not:f { \__fp_parse:n {#2} } } } \cs_new_protected:Npn \fp_gset:Nn #1#2 { \tl_gset:Nx #1 { \exp_not:f { \__fp_parse:n {#2} } } } \cs_new_protected:Npn \fp_const:Nn #1#2 { \tl_const:Nx #1 { \exp_not:f { \__fp_parse:n {#2} } } } \cs_generate_variant:Nn \fp_set:Nn {c} \cs_generate_variant:Nn \fp_gset:Nn {c} \cs_generate_variant:Nn \fp_const:Nn {c} \cs_new_eq:NN \fp_set_eq:NN \tl_set_eq:NN \cs_new_eq:NN \fp_gset_eq:NN \tl_gset_eq:NN \cs_generate_variant:Nn \fp_set_eq:NN { c , Nc , cc } \cs_generate_variant:Nn \fp_gset_eq:NN { c , Nc , cc } \cs_new_protected:Npn \fp_zero:N #1 { \fp_set_eq:NN #1 \c_zero_fp } \cs_new_protected:Npn \fp_gzero:N #1 { \fp_gset_eq:NN #1 \c_zero_fp } \cs_generate_variant:Nn \fp_zero:N { c } \cs_generate_variant:Nn \fp_gzero:N { c } \cs_new_protected:Npn \fp_zero_new:N #1 { \fp_if_exist:NTF #1 { \fp_zero:N #1 } { \fp_new:N #1 } } \cs_new_protected:Npn \fp_gzero_new:N #1 { \fp_if_exist:NTF #1 { \fp_gzero:N #1 } { \fp_new:N #1 } } \cs_generate_variant:Nn \fp_zero_new:N { c } \cs_generate_variant:Nn \fp_gzero_new:N { c } \cs_new_protected_nopar:Npn \fp_add:Nn { \__fp_add:NNNn \fp_set:Nn + } \cs_new_protected_nopar:Npn \fp_gadd:Nn { \__fp_add:NNNn \fp_gset:Nn + } \cs_new_protected_nopar:Npn \fp_sub:Nn { \__fp_add:NNNn \fp_set:Nn - } \cs_new_protected_nopar:Npn \fp_gsub:Nn { \__fp_add:NNNn \fp_gset:Nn - } \cs_new_protected:Npn \__fp_add:NNNn #1#2#3#4 { #1 #3 { #3 #2 \__fp_parse:n {#4} } } \cs_generate_variant:Nn \fp_add:Nn { c } \cs_generate_variant:Nn \fp_gadd:Nn { c } \cs_generate_variant:Nn \fp_sub:Nn { c } \cs_generate_variant:Nn \fp_gsub:Nn { c } \cs_new_protected:Npn \fp_show:N #1 { \fp_if_exist:NTF #1 { \__msg_show_variable:n { > ~ \fp_to_tl:N #1 } } { \__msg_kernel_error:nnx { kernel } { variable-not-defined } { \token_to_str:N #1 } } } \cs_new_protected:Npn \fp_show:n #1 { \__msg_show_variable:n { > ~ \fp_to_tl:n {#1} } } \cs_generate_variant:Nn \fp_show:N { c } \fp_const:Nn \c_e_fp { 2.718 2818 2845 9045 } \fp_const:Nn \c_one_fp { 1 } \fp_const:Nn \c_pi_fp { 3.141 5926 5358 9793 } \fp_const:Nn \c_one_degree_fp { 0.0 1745 3292 5199 4330 } \fp_new:N \l_tmpa_fp \fp_new:N \l_tmpb_fp \fp_new:N \g_tmpa_fp \fp_new:N \g_tmpb_fp %% File: l3fp-old.dtx Copyright (C) 2012 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3kernel bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX3 Project Team. %% %% ----------------------------------------------------------------------- %% \fp_const:Nn \c_undefined_fp { nan } \prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF } { \exp_after:wN \__fp_if_undefined:w #1 } \cs_new:Npn \__fp_if_undefined:w \s__fp \__fp_chk:w #1#2; { \if_int_compare:w #1 > \c_one \prg_return_true: \else: \prg_return_false: \fi: } \prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF } { \exp_after:wN \__fp_if_zero:w #1 } \cs_new:Npn \__fp_if_zero:w \s__fp \__fp_chk:w #1#2; { \if_meaning:w #1 0 \prg_return_true: \else: \prg_return_false: \fi: } \cs_new_protected_nopar:Npn \fp_abs:N { \__fp_abs:NNN \tl_set:Nx \__fp_abs_o:w } \cs_new_protected_nopar:Npn \fp_gabs:N { \__fp_abs:NNN \tl_gset:Nx \__fp_abs_o:w } \cs_new_protected_nopar:Npx \fp_neg:N { \exp_not:N \__fp_abs:NNN \exp_not:N \tl_set:Nx \exp_not:c { __fp_-_o:w } } \cs_new_protected_nopar:Npx \fp_gneg:N { \exp_not:N \__fp_abs:NNN \exp_not:N \tl_gset:Nx \exp_not:c { __fp_-_o:w } } \cs_new_protected:Npn \__fp_abs:NNN #1#2#3 { #1 #3 { \exp_after:wN #2 #3 \prg_do_nothing: } } \cs_generate_variant:Nn \fp_abs:N { c } \cs_generate_variant:Nn \fp_gabs:N { c } \cs_generate_variant:Nn \fp_neg:N { c } \cs_generate_variant:Nn \fp_gneg:N { c } \cs_new_protected_nopar:Npn \fp_mul:Nn { \__fp_mul:NNNn \fp_set:Nn * } \cs_new_protected_nopar:Npn \fp_gmul:Nn { \__fp_mul:NNNn \fp_gset:Nn * } \cs_new_protected_nopar:Npn \fp_div:Nn { \__fp_mul:NNNn \fp_set:Nn / } \cs_new_protected_nopar:Npn \fp_gdiv:Nn { \__fp_mul:NNNn \fp_gset:Nn / } \cs_new_protected_nopar:Npn \fp_pow:Nn { \__fp_mul:NNNn \fp_set:Nn ^ } \cs_new_protected_nopar:Npn \fp_gpow:Nn { \__fp_mul:NNNn \fp_gset:Nn ^ } \cs_new_protected:Npn \__fp_mul:NNNn #1#2#3#4 { #1 #3 { #3 #2 \__fp_parse:n {#4} } } \cs_generate_variant:Nn \fp_mul:Nn { c } \cs_generate_variant:Nn \fp_gmul:Nn { c } \cs_generate_variant:Nn \fp_div:Nn { c } \cs_generate_variant:Nn \fp_gdiv:Nn { c } \cs_generate_variant:Nn \fp_pow:Nn { c } \cs_generate_variant:Nn \fp_gpow:Nn { c } \cs_set_protected:Npn \__fp_tmp:w #1#2#3#4#5 { \cs_new_protected_nopar:Npn #1 { #5 {#4} \tl_set_eq:NN #3 } \cs_new_protected_nopar:Npn #2 { #5 {#4} \tl_gset_eq:NN #3 } \cs_generate_variant:Nn #1 { c } \cs_generate_variant:Nn #2 { c } } \__fp_tmp:w \fp_exp:Nn \fp_gexp:Nn \__fp_exp_o:w {exp} \__fp_assign_to:nNNNn \__fp_tmp:w \fp_ln:Nn \fp_gln:Nn \__fp_ln_o:w {ln } \__fp_assign_to:nNNNn \__fp_tmp:w \fp_sin:Nn \fp_gsin:Nn \__fp_sin_o:w {sin} \__fp_assign_to:nNNNn \__fp_tmp:w \fp_cos:Nn \fp_gcos:Nn \__fp_cos_o:w {cos} \__fp_assign_to:nNNNn \__fp_tmp:w \fp_tan:Nn \fp_gtan:Nn \__fp_tan_o:w {tan} \__fp_assign_to:nNNNn \cs_new_protected:Npn \__fp_assign_to:nNNNn #1#2#3#4#5 { \exp_after:wN \__fp_assign_to_i:wNNNn \tex_romannumeral:D -`0 \__fp_parse:n {#5} {#1} #2#3#4 } \cs_new_protected:Npn \__fp_assign_to_i:wNNNn \s__fp \__fp_chk:w #1#2#3; #4 { \exp_args:Nc \__fp_assign_to_ii:NnNNN { c__fp_ #4 [ #1 # 2 \if_meaning:w 1 #1 #3 \fi: ] _fp } { #1#2#3 } } \cs_new_protected:Npn \__fp_assign_to_ii:NnNNN #1#2#3#4#5 { \cs_if_exist:NF #1 { \tl_const:Nx #1 { #4 \s__fp \__fp_chk:w #2; } } #3 #5 #1 } \cs_new_protected_nopar:Npn \fp_compare:NNNTF { \fp_compare:nNnTF } \cs_new_protected_nopar:Npn \fp_compare:NNNT { \fp_compare:nNnT } \cs_new_protected_nopar:Npn \fp_compare:NNNF { \fp_compare:nNnF } \cs_new_protected_nopar:Npn \fp_round_places:Nn { \__fp_round_places:NNn \tl_set:Nx } \cs_new_protected_nopar:Npn \fp_ground_places:Nn { \__fp_round_places:NNn \tl_gset:Nx } \cs_new_protected:Npn \__fp_round_places:NNn #1#2#3 { #1 #2 { \exp_after:wN \exp_after:wN \exp_after:wN \__fp_round:Nwn \exp_after:wN \exp_after:wN \exp_after:wN \__fp_round_to_nearest:NNN \exp_after:wN #2 \exp_after:wN { \int_use:N \__int_eval:w #3 } } } \cs_generate_variant:Nn \fp_round_places:Nn { c } \cs_generate_variant:Nn \fp_ground_places:Nn { c } \cs_new_protected:Npn \fp_round_figures:Nn #1#2 { \__fp_round_places:NNn \tl_set:Nx #1 { #2 - \exp_after:wN \__fp_exponent:w #1 } } \cs_new_protected:Npn \fp_ground_figures:Nn #1#2 { \__fp_round_places:NNn \tl_gset:Nx #1 { #2 - \exp_after:wN \__fp_exponent:w #1 } } \cs_generate_variant:Nn \fp_round_figures:Nn { c } \cs_generate_variant:Nn \fp_ground_figures:Nn { c } %% %% %% End of file `l3fp.sty'.