%% %% 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-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. %% %% ----------------------------------------------------------------------- %% \RequirePackage{l3bootstrap} \GetIdInfo$Id: l3fp.dtx 4449 2013-01-19 23:55:05Z bruno $ {L3 Floating points} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \__expl_package_check: %% File: l3fp-aux.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_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; } \__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} } \cs_new:Npn \__fp_pack:NNNNNwn #1 #2#3#4#5 #6; #7 { + #1#2#3#4#5 ; {#7} {#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} } \cs_new:Npn \__fp_pack_big:NNNNNNwn #1#2 #3#4#5#6 #7; #8 { + #1#2#3#4#5#6 ; {#8} {#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 { \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 \else: \__fp_case_return:nw \use_ii:nn \fi: } \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 \if_int_compare:w #2 > \c_eight \exp_after:wN \exp_after:wN \exp_after:wN \use_iii:nnn \else: \__fp_decimate:nNnnnn { \c_sixteen - #2 } \__fp_small_int_test:NnnwNTF #3 #1 \fi: \else: \exp_after:wN \use_iii:nnn \fi: ; } \cs_new:Npn \__fp_small_int_test:NnnwNTF #1#2#3#4; #5 { \if_meaning:w 0 #1 \exp_after:wN \__fp_small_int_true:wTF \__int_value:w \if_meaning:w 2 #5 - \fi: #3 \else: \exp_after:wN \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-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_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:nf ##1##2 } { #1 \__fp_error:nnfn { 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:nf #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_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:Nww #1#2 ; #3 ; { \__fp_small_int:wTF #3; { \__fp_round:Nwn #1#2; } { \__fp_invalid_operation_tl_o:nf { round } { \__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-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_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_operand:Nw #1 #2 { \if_catcode:w \tex_relax:D #2 \if_meaning:w \tex_relax:D #2 \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_operand_relax:NN \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_operand_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_operand_digit:NN \else: \exp_after:wN \exp_after:wN \exp_after:wN \__fp_parse_operand_other:NN \fi: \fi: #1 #2 } \group_begin: \char_set_catcode_other:N \P \char_set_catcode_other:N \T \tl_to_lowercase:n { \group_end: \cs_new:Npn \__fp_parse_operand_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_operand_register_aux:www \tex_the:D \exp_after:wN #2 \exp_after:wN P \exp_after:wN T \exp_after:wN \q_stop \__int_value:w \__fp_parse_exponent:N } \cs_new:Npn \__fp_parse_operand_register_aux:www #1 PT #2 \q_stop #3 ; { \__fp_parse:n { #1 e #3 } } } \cs_new:Npn \__fp_parse_operand_relax:NN #1#2 { \cs:w __fp_parse_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_eq:NN \__fp_parse_exp_after_f:nw \__fp_exp_after_f:nw \cs_new:Npn \__fp_parse_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_parse_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_operand_other:NN #1 #2 { \if_int_compare:w \__int_eval:w \tex_uccode:D `#2 / 26 = \c_three \exp_after:wN \__fp_parse_operand_other_word_aux:Nw \exp_after:wN #1 \tex_romannumeral:D \exp_after:wN \__fp_parse_letters:NN \exp_after:wN #2 \tex_romannumeral:D \else: \exp_after:wN \__fp_parse_operand_other_prefix_aux: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_letters:NN #1#2 { \exp_after:wN \c_zero \exp_after:wN #1 \tex_romannumeral:D \if_int_compare:w \if_catcode:w \tex_relax:D #2 \c_zero \else: \__int_eval:w \tex_uccode:D `#2 / 26 \fi: = \c_three \exp_after:wN \__fp_parse_letters:NN \exp_after:wN #2 \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN \c_zero \exp_after:wN ; \exp_after:wN #2 \fi: } \cs_new:Npn \__fp_parse_operand_other_word_aux: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_eq:NN \s__fp_unknown \tex_relax:D \cs_new:Npn \__fp_parse_operand_other_prefix_aux:NNN #1#2#3 { \if_meaning:w \tex_relax:D #3 \exp_after:wN \__fp_parse_operand_other_prefix_unknown:NNN \exp_after:wN #2 \fi: #3 #1 } \cs_new:Npn \__fp_parse_operand_other_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_operand:Nw #3 } } \cs_new:Npn \__fp_parse_operand_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_trim_zeros:N #1 { \if:w 0 #1 \exp_after:wN \__fp_parse_trim_zeros:N \tex_romannumeral:D \else: \if:w . #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 #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 . #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 . #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_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 #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 \tex_relax:D #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 - #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 \tex_relax:D #1 \if_meaning:w \tex_relax:D #1 \if_int_compare:w \pdftex_strcmp:D { \s__fp } { #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:Npn \__fp_cfs_round_loop:N #1 { \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: + \c_one \if:w 0 #1 \exp_after:wN \__fp_cfs_round_loop:N \tex_romannumeral:D \else: \exp_after:wN \__fp_cfs_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_cfs_round_up:N #1 { \if_int_compare:w \c_nine < 1 \token_to_str:N #1 \exp_stop_f: + 1 \exp_after:wN \__fp_cfs_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_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_after:wNN \int_use:N \__int_eval:w \c_one \exp_after:wN \__fp_cfs_round_loop:N \else: %^^A could be dot, or e, or other \exp_after:wN \__fp_parse_large_round_dot_test:NNw \exp_after:wN #1 \exp_after:wN #2 \fi: } \cs_new:Npn \__fp_parse_large_round_dot_test:NNw #1#2 { \if:w . #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_after:wNN #1 ; #2 #3 { \if:w . #3 \exp_after:wN \__fp_parse_large_round_after_aux:wN \int_use:N \__int_eval:w #1 + \c_zero * \__int_eval:w \c_zero \exp_after:wN \__fp_cfs_round_loop:N \tex_romannumeral:D \exp_after:wN \__fp_parse_expand:w \else: + #2 \exp_after:wN ; \int_use:N \__int_eval:w #1 + \exp_after:wN \__fp_parse_exponent:N \exp_after:wN #3 \fi: } \cs_new:Npn \__fp_parse_large_round_after_aux: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_small_round_after:wN \int_use:N \__int_eval:w \c_zero \exp_after:wN \__fp_cfs_round_loop:N \tex_romannumeral:D \else: \__fp_parse_exponent:Nw #2 \fi: \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_small_round_after:wN #1; #2 { + #2 \exp_after:wN ; \__int_value:w \__fp_parse_exponent:N } \cs_new:Npn \__fp_parse:n #1 { \tex_romannumeral:D \exp_after:wN \__fp_parse_after:ww \tex_romannumeral:D \__fp_parse_until:Nw \c_minus_one \__fp_parse_expand:w #1 \s__fp_mark \s__fp_stop } \cs_new:Npn \__fp_parse_after:ww #1@ #2 \s__fp_stop { \c_zero #1 } \cs_new:Npn \__fp_parse_until:Nw #1 { -`0 \exp_after:wN \__fp_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \exp_after:wN \__fp_parse_operand:Nw \exp_after:wN #1 \tex_romannumeral:D } \cs_new:Npn \__fp_parse_until_test:NwN #1 #2 @ #3 { #3 #1 #2 @ } \cs_new_eq:NN \__fp_parse_stop_until:N \use_none:n \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 \tex_relax:D #2 \if_int_compare:w \pdftex_strcmp:D { \s__fp_mark } { #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 \tex_uccode:D `#2 / 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 \tex_relax:D #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_apply_binary:NwNwN #1 #2#3@ #4 #5#6@ #7 { \exp_after:wN \__fp_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \cs:w __fp \__fp_type_from_scan:N #2 _ #4 \__fp_type_from_scan:N #5 _o:ww \cs_end: #2#3 #5#6 \tex_romannumeral:D -`0 #7 #1 } \cs_new:Npn \__fp_parse_apply_unary_array:NNwN #1#2#3@#4 { #2 #3 @ \tex_romannumeral:D -`0 #4 #1 } \cs_new:Npn \__fp_parse_apply_unary:NNwN #1#2#3@#4 { #2 #3 \tex_romannumeral:D -`0 #4 #1 } \cs_new:Npn \__fp_parse_unary_type:N #1 { \__fp_type_from_scan:N #1 _o:w \cs_end: #1 } \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 \__fp_tmp:w { pt } \c_one_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 {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 \dim_to_fp:n \exp_after:wN { \dim_use:N \__dim_eval:w 1 #1 \exp_after:wN } \tex_romannumeral:D -`0 \__fp_parse_infix:NN } } \tl_map_inline:nn { {abs} {cos} {cot} {csc} {exp} {ln} {sec} {sin} {tan} } { \cs_new:cpn { __fp_parse_word_#1:N } ##1 { \exp_after:wN \__fp_parse_apply_unary:NNwN \exp_after:wN ##1 \cs:w __fp_ #1 \exp_after:wN \__fp_parse_unary_type:N \tex_romannumeral:D \__fp_parse_until:Nw \c_fifteen \__fp_parse_expand:w } } \cs_set_protected:Npn \__fp_tmp:w #1#2 { \cs_new:Npn #1 ##1 { \exp_after:wN \__fp_parse_apply_unary_array:NNwN \exp_after:wN ##1 \exp_after:wN #2 \tex_romannumeral:D \__fp_parse_until:Nw \c_sixteen \__fp_parse_expand:w } } \__fp_tmp:w \__fp_parse_word_max:N \__fp_max_o:w \__fp_tmp:w \__fp_parse_word_min:N \__fp_min_o:w \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: \exp_after:wN \__fp_parse_apply_round:NNwN \exp_after:wN #1 \exp_after:wN \__fp_round_to_nearest:NNN \tex_romannumeral:D \__fp_parse_until:Nw \c_sixteen \__fp_parse_expand:w #2 } \cs_new:Npn \__fp_parse_round:Nw #1 #2 \__fp_round_to_nearest:NNN #3 \__fp_parse_expand:w #4 { #2 #1 #3 \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_apply_round:NNwN #1#2#3@#4 { \if_case:w \__int_eval:w \__fp_array_count:n {#3} - \c_one \__int_eval_end: \__fp_round:Nwn #2 #3 {0} \tex_romannumeral:D \or: \__fp_round:Nww #2 #3 \tex_romannumeral:D \else: \__msg_kernel_expandable_error:nnnnn { kernel } { fp-num-args } { round() } { 1 } { 2 } \exp_after:wN \c_nan_fp \tex_romannumeral:D \fi: -`0 #4 #1 } \cs_new_eq:cN { __fp_parse_prefix_+:Nw } \__fp_parse_operand:Nw \cs_set_protected:Npn \__fp_tmp:w #1#2 { \cs_new:cpn { __fp_parse_prefix_#1:Nw } ##1 { \exp_after:wN \__fp_parse_apply_unary:NNwN \exp_after:wN ##1 \cs:w __fp_ #2 \exp_after:wN \__fp_parse_unary_type:N \tex_romannumeral:D \if_int_compare:w \c_twelve < ##1 \__fp_parse_until:Nw ##1 \else: \__fp_parse_until:Nw \c_twelve \fi: \__fp_parse_expand:w } } \__fp_tmp:w - { - } \__fp_tmp:w ! { ! } \group_begin: \char_set_catcode_letter:N \) \cs_new:cpn { __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_until:Nw \c_one \else: \__fp_parse_until: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 @ \__fp_parse_stop_until:N #3 } } \group_end: \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 } \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_until:Nw #4 \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \__fp_parse_stop_until:N \exp_after:wN #1 \fi: } } \group_begin: \char_set_catcode_other:N \& \__fp_tmp:w \__fp_parse_infix_juxtapose:N * \c_thirty_two \c_thirty_two \exp_args:Nc \__fp_tmp:w { __fp_parse_infix_ / :N } / \c_ten \c_ten \exp_args:Nc \__fp_tmp:w { __fp_parse_infix_mul:N } * \c_ten \c_ten \exp_args:Nc \__fp_tmp:w { __fp_parse_infix_ - :N } - \c_nine \c_nine \exp_args:Nc \__fp_tmp:w { __fp_parse_infix_ + :N } + \c_nine \c_nine \exp_args:Nc \__fp_tmp:w { __fp_parse_infix_and:N } & \c_five \c_five \exp_args:Nc \__fp_tmp:w { __fp_parse_infix_ or:N } | \c_four \c_four \group_end: \group_begin: \char_set_catcode_letter:N ^ \__fp_tmp:w \__fp_parse_infix_^:N ^ \c_fifteen \c_fourteen \cs_new:cpn { __fp_parse_infix_*:N } #1#2 { \if:w * #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 | #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 & #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: \cs_new:cpn { __fp_parse_infix_<:N } #1 { \__fp_infix_compare:N #1 \c_one_fp \c_zero_fp \c_zero_fp \c_zero_fp \c_zero_fp < } \cs_new:cpn { __fp_parse_infix_=:N } #1 { \__fp_infix_compare:N #1 \c_one_fp \c_zero_fp \c_zero_fp \c_zero_fp \c_zero_fp = } \cs_new:cpn { __fp_parse_infix_>:N } #1 { \__fp_infix_compare:N #1 \c_one_fp \c_zero_fp \c_zero_fp \c_zero_fp \c_zero_fp > } \cs_new:cpn { __fp_parse_infix_!:N } #1 { \exp_after:wN \__fp_parse_infix_excl_aux:NN \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_expand:w } \cs_new:Npn \__fp_parse_infix_excl_aux:NN #1#2 { \__fp_infix_compare:N #1 \c_zero_fp \c_one_fp \c_one_fp \c_one_fp \c_one_fp #2 } \cs_new:Npn \__fp_parse_infix_excl_error: { \__msg_kernel_expandable_error:nnnn { kernel } { fp-missing } { = } { ~after~!. } } \cs_new:Npn \__fp_infix_compare:N #1 { \if_int_compare:w #1 < \c_seven \exp_after:wN \__fp_parse_compare:NNNNNNw \exp_after:wN \__fp_parse_infix_excl_error: \else: \exp_after:wN @ \exp_after:wN \__fp_parse_stop_until:N \exp_after:wN \__fp_infix_compare:N \fi: } \cs_new:Npn \__fp_parse_compare:NNNNNNw #1#2#3#4#5#6#7 { \if_case:w \if_catcode:w \tex_relax:D #7 \c_minus_one \else: \__int_eval:w `#7 - `< \__int_eval_end: \fi: \__fp_parse_compare_expand:NNNNNw #2#2#4#5#6 \or: \__fp_parse_compare_expand:NNNNNw #2#3#2#5#6 \or: \__fp_parse_compare_expand:NNNNNw #2#3#4#2#6 \or: \__fp_parse_compare_expand:NNNNNw #2#3#4#5#2 \else: #1 \__fp_parse_compare_end:NNNN #3#4#5#6#7 \fi: } \cs_new:Npn \__fp_parse_compare_expand:NNNNNw #1#2#3#4#5 { \exp_after:wN \__fp_parse_compare:NNNNNNw \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:NNNN #1#2#3#4#5 \fi: { \fi: \exp_after:wN @ \exp_after:wN \__fp_parse_apply_compare:NwNNNNwN \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 \tex_romannumeral:D \__fp_parse_until:Nw \c_seven \__fp_parse_expand:w #5 } \cs_new:Npn \__fp_parse_apply_compare:NwNNNNwN #1 #2@ #3#4#5#6 #7@ #8 { \exp_after:wN \__fp_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \if_case:w \__fp_compare_back:ww #7 #2 \exp_stop_f: #4 \or: #5 \or: #6 \else: #3 \fi: \tex_romannumeral:D -`0 #8 #1 } \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_until:Nw \c_three \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \__fp_parse_stop_until: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_until:Nw \c_two \exp_after:wN \__fp_parse_expand:w \else: \exp_after:wN @ \exp_after:wN \__fp_parse_stop_until: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_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 \__fp_parse_stop_until:N \exp_after:wN \__fp_parse_infix_):N \fi: } \group_end: \cs_new:Npn \__fp_parse_infix_end:N #1 { @ \__fp_parse_stop_until: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_one \exp_after:wN @ \exp_after:wN \__fp_parse_stop_until: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_until:Nw \c_one \exp_after:wN \__fp_parse_expand:w \fi: } \cs_new:Npn \__fp_parse_infix_comma:w #1 @ { #1 @ \__fp_parse_stop_until:N } \cs_new:Npn \__fp_parse_infix_comma_gobble:w #1 @ { \__msg_kernel_expandable_error:nn { kernel } { fp-extra-comma } @ \__fp_parse_stop_until:N } \group_end: \__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-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. %% %% ----------------------------------------------------------------------- %% \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_max_o:w #1 @ { \exp_after:wN \__fp_minmax_loop:Nww \exp_after:wN \c_minus_one \c_minus_inf_fp #1 \s__fp \__fp_chk:w { 3 \__fp_minmax_break_o:w } ; } \cs_new:Npn \__fp_min_o:w #1 @ { \exp_after:wN \__fp_minmax_loop:Nww \exp_after:wN \c_one \c_inf_fp #1 \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_!_o:w } \s__fp \__fp_chk:w #1#2; { \if_meaning:w 0 #1 \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_until:Nw \c_two \__fp_parse_expand:w \else: \__msg_kernel_expandable_error:nnnn { kernel } { fp-missing } { : } { ~for~?: } \exp_after:wN \__fp_parse_until_test: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_until_test: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_until_test: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-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_basics_pack_low:NNNNNw #1 #2#3#4#5 #6; { \if_meaning:w 2 #1 + \c_one \fi: ; {#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:cpn { __fp_-_o:w } #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_abs_o:w \s__fp \__fp_chk:w #1 #2 { \exp_after:wN \__fp_exp_after_o:w \exp_after:wN \s__fp \exp_after:wN \__fp_chk:w \exp_after:wN #1 \__int_value:w \if_meaning:w 1 #2 1 \else: 0 \fi: \exp_stop_f: } %% File: l3fp-extended.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. %% %% ----------------------------------------------------------------------- %% \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_mul_after:wn #1; #2 { #2 {#1} } \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:wn \int_use:N \__int_eval:w \c__fp_leading_shift_int \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#6 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#7 + #2*#6 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#8 + #2*#7 + #3*#6 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#9 + #2*#8 + #3*#7 + #4*#6 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #2*#9 + #3*#8 + #4*#7 + ( #3*#9 + #4*#8 + \__fp_fixed_mul:nnnnnnnwn #5 {#6}{#7} {#1}{#2} } \cs_new:Npn \__fp_fixed_mul:nnnnnnnwn #1#2 #3#4 #5#6 #7#8 ; #9 { #1*#4 + #2*#3 + #5*#8 + #6*#7 ) / \c_ten_thousand + #1*#3 + #5*#7 ; {#9} ; } \cs_new:Npn \__fp_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8; #9 { \exp_after:wN \__fp_fixed_mul_after:wn \int_use:N \__int_eval:w \c__fp_big_leading_shift_int \exp_after:wN \__fp_pack_big:NNNNNNwn \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 ; {#9} ; } \cs_new:Npn \__fp_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8; #9 { \exp_after:wN \__fp_fixed_mul_after:wn \int_use:N \__int_eval:w \c__fp_big_leading_shift_int \exp_after:wN \__fp_pack_big:NNNNNNwn \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 ; {#9} ; } \cs_new:Npn \__fp_fixed_one_minus_mul:wwn #1; #2; #3 { \exp_after:wN \__fp_fixed_mul_after:wn \int_use:N \__int_eval:w \c__fp_big_leading_shift_int \exp_after:wN \__fp_pack_big:NNNNNNwn \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + 1 0000 0000 \__fp_fixed_mul_add:Nwnnnwnnn - ; #2 ; #1 ; #2 ; - ; {#3} ; } \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:NNNNNNwn \int_use:N \__int_eval:w \c__fp_big_middle_shift_int #1 #7*#4 #1 #8*#3 \exp_after:wN \__fp_pack_big:NNNNNNwn \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:NNNNNNwn \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:NNNNNNwn \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_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 { + \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 ; } \cs_new:Npn \__fp_fixed_inv_to_float:wN #1#2; #3 { + \__int_eval:w % ^^A todo: remove the +? \if_int_compare:w #1 < \c_one_thousand \__fp_fixed_dtf_zeros:wNnnnnnn \fi: \__fp_fixed_dtf_no_zero:Nwn + {#1} #2 \s__fp \__fp_fixed_dtf_approx:n {10000} {0000} {0000} {0000} {0000} {0000} ; } \cs_new:Npn \__fp_fixed_div_to_float:ww #1#2; #3#4; { \if_int_compare:w #1 < \c_one_thousand \__fp_fixed_dtf_zeros:wNnnnnnn \fi: \__fp_fixed_dtf_no_zero:Nwn - {#1} #2 \s__fp { \if_int_compare:w #3 < \c_one_thousand \__fp_fixed_dtf_zeros:wNnnnnnn \fi: \__fp_fixed_dtf_no_zero:Nwn + {#3} #4 \s__fp \__fp_fixed_dtf_approx:n } } \cs_new:Npn \__fp_fixed_dtf_no_zero:Nwn #1#2 \s__fp #3 { #3 #2; } \cs_new:Npn \__fp_fixed_dtf_zeros:wNnnnnnn \fi: \__fp_fixed_dtf_no_zero:Nwn #1#2#3#4#5#6#7 { \fi: #1 \c_minus_one \exp_after:wN \use_i_ii:nnn \exp_after:wN \__fp_fixed_dtf_zeros:NN \exp_after:wN #1 \int_use:N \__int_eval:w 10 0000 + #2 \__int_eval_end: #3#4#5#6#7 ; 1 ; } \cs_new:Npn \__fp_fixed_dtf_zeros:NN #1#2 { \if_meaning:w 0 #2 #1 \c_one \else: \__fp_fixed_dtf_zeros_end:wNww #2 \fi: \__fp_fixed_dtf_zeros:NN #1 } \cs_new:Npn \__fp_fixed_dtf_zeros_end:wNww #1 \fi: \__fp_fixed_dtf_zeros:NN #2 #3; #4 \s__fp { \fi: \if_meaning:w ; #1 #2 \c_two * \c__fp_max_exponent_int \use_i_ii:nnn \fi: \__fp_fixed_dtf_zeros_auxi:ww #1#3 0000 0000 0000 0000 0000 0000 ; } \cs_new:Npn \__fp_fixed_dtf_zeros_auxi:ww { \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_fixed_dtf_zeros_auxii:ww ; } \cs_new:Npn \__fp_fixed_dtf_zeros_auxii:ww #1; #2; #3 { #3 #1; } \cs_new:Npn \__fp_fixed_dtf_approx:n #1 { \exp_after:wN \__fp_fixed_dtf_approx:wnn \int_use:N \__int_eval:w 10 0000 0000 / ( #1 + \c_one ) ; {#1} } \cs_new:Npn \__fp_fixed_dtf_approx:wnn #1; #2#3 { \exp_after:wN \__fp_fixed_dtf_approx:NNNNNw \int_use:N \__int_eval:w 10 0000 0000 - 1750 + #1000 + (10 0000 0000/#2-#1) * (1000-#3/10) ; {#2}{#3} } \cs_new:Npn \__fp_fixed_dtf_approx:NNNNNw 1#1#2#3#4#5#6; #7; #8; { + \c_four % because of the line below "dtf_epsilon" here. \__fp_fixed_mul:wwn {000#1}{#2#3#4#5}{#6}{0000}{0000}{0000} ; #7; \__fp_fixed_dtf_epsilon:wN \__fp_fixed_mul:wwn {000#1}{#2#3#4#5}{#6}{0000}{0000}{0000} ; \__fp_fixed_mul:wwn #8; \__fp_fixed_to_float:wN ? } \cs_new:Npn \__fp_fixed_dtf_epsilon:wN #1#2#3#4#5#6; { \exp_after:wN \__fp_fixed_dtf_epsilon:NNNNNww \int_use:N \__int_eval:w 1 9999 9998 - #3#4 + \exp_after:wN \__fp_fixed_dtf_epsilon_pack:NNNNNw \int_use:N \__int_eval:w 2 0000 0000 - #5#6 ; {0000} ; } \cs_new:Npn \__fp_fixed_dtf_epsilon_pack:NNNNNw #1#2#3#4#5#6; { #1 ; {#2#3#4#5} {#6} } \cs_new:Npn \__fp_fixed_dtf_epsilon:NNNNNww #1#2#3#4#5#6; #7; { \__fp_fixed_mul:wwn %^^A todo: optimize to use \__fp_mul_significand. {0000} {#2#3#4#5} {#6} #7 ; {0000} {#2#3#4#5} {#6} #7 ; \__fp_fixed_add_one:wN \__fp_fixed_mul:wwn {10000} {#2#3#4#5} {#6} #7 ; } %% File: l3fp-expo.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. %% %% ----------------------------------------------------------------------- %% \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 \s__fp \__fp_chk:w #1 #2 { \if_meaning:w 2 #2 \__fp_case_use:nw { \__fp_invalid_operation_o:nw { ln } } \fi: \if_case:w #1 \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 #1#2 } \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 \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: \exp_after:wN \__fp_exp_normal:w \or: \if_meaning:w 0 #2 \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 #1#2 } \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:Nwnnnnnwn % n\ln(10) - (-\ln(x)) \exp_after:wN + \else: \exp_after:wN \__fp_pow_exponent:Nwnnnnnwn % -( |n|\ln(10) + (-\ln(x)) ) \exp_after:wN - \fi: #2; #1; } \cs_new:Npn \__fp_pow_exponent:Nwnnnnnwn #1#2; #3#4#5#6#7#8; #9 { %^^A todo: use that in ln. \exp_after:wN \__fp_fixed_mul_after:wn \int_use:N \__int_eval:w \c__fp_leading_shift_int \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int #1#2*23025 - #1 #3 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int #1 #2*8509 - #1 #4 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int #1 #2*2994 - #1 #5 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int #1 #2*0456 - #1 #6 \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_trailing_shift_int #1 #2*8401 - #1 #7 #1 ( #2*7991 - #8 ) / 1 0000 ; {#9} ; } \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 ; \cs:w __fp_-_o:w \exp_after:wN \cs_end: \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_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-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_sin_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return_same_o:w \or: \__fp_case_use:nw { \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_o:w \__fp_sin_series:NNwww \__fp_fixed_to_float:wN #2 \c_zero } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { sin } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } \cs_new:Npn \__fp_cos_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: \__fp_case_use:nw { \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_one_o:w \__fp_sin_series:NNwww \__fp_fixed_to_float:wN 0 \c_two } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { cos } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } \cs_new:Npn \__fp_csc_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_cot_zero_o:Nnw #2 { csc } \or: \__fp_case_use:nw { \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_inv_o:w \__fp_sin_series:NNwww \__fp_fixed_inv_to_float:wN #2 \c_zero } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { csc } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } \cs_new:Npn \__fp_sec_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: \__fp_case_use:nw { \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_one_o:w \__fp_sin_series:NNwww \__fp_fixed_inv_to_float:wN 0 \c_two } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { sec } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } \cs_new:Npn \__fp_tan_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return_same_o:w \or: \__fp_case_use:nw { \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_o:w \__fp_tan_series_o:NNwww 0 #2 \c_one } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { tan } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } \cs_new:Npn \__fp_cot_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_cot_zero_o:Nnw #2 { cot } \or: \__fp_case_use:nw { \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_inv_o:w \__fp_tan_series_o:NNwww 2 #2 \c_three } \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { cot } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } \cs_new:Npn \__fp_cot_zero_o:Nnw #1 #2 #3 \fi: { \fi: \if_meaning:w 0 #1 \exp_after:wN \__fp_division_by_zero_o:Nnw \exp_after:wN \c_inf_fp \else: \exp_after:wN \__fp_division_by_zero_o:Nnw \exp_after:wN \c_minus_inf_fp \fi: {#2} } \cs_new:Npn \__fp_trig_exponent:NNNNNwn #1#2#3#4#5 \s__fp \__fp_chk:w 1#6#7 { \if_int_compare:w #7 > - \c_eight \exp_after:wN #2 \exp_after:wN #3 \exp_after:wN #4 \int_use:N \__int_eval:w #5 \if_int_compare:w #7 > \c_zero \exp_after:wN \__fp_trig_large:ww \__int_value:w \else: \exp_after:wN \__fp_trig_small:ww \__int_value:w \fi: \else: \exp_after:wN #1 \exp_after:wN #6 \fi: #7 ; } \cs_new:Npn \__fp_trig_epsilon_o:w #1 #2 ; { \__fp_exp_after_o:w \s__fp \__fp_chk:w 1 #1 {#2} } \cs_new:Npn \__fp_trig_epsilon_one_o:w #1 ; #2 ; { \exp_after:wN \c_one_fp } \group_begin: \char_set_catcode_letter:N / \cs_new:Npn \__fp_trig_epsilon_inv_o:w #1 #2 ; { \exp_after:wN \__fp_/_o:ww \c_one_fp \s__fp \__fp_chk:w 1 #1 {#2} } \group_end: \cs_new:Npn \__fp_trig_small:ww #1; #2#3#4#5; { \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN \exp_after:wN . \exp_after:wN ; \tex_romannumeral:D -`0 \prg_replicate:nn { - #1 } { 0 } #2#3#4#5 0000 0000 ; } \cs_new:Npn \__fp_trig_large:ww #1; #2#3; { \__fp_trig_large:www #2; #3 ; #1; } \cs_new:Npn \__fp_trig_large:www #1; #2; #3; { \if_meaning:w 0 #3 \__fp_trig_large_break:w \fi: \exp_after:wN \__fp_trig_large_o:wnnnn \int_use:N \__int_eval:w ( #1 - 3141 ) / 6283 ; {#1} #2 \exp_after:wN ; \int_use:N \__int_eval:w \c_minus_one + #3; } \cs_new:Npn \__fp_trig_large_o:wnnnn #1; #2#3#4#5 { \exp_after:wN \__fp_trig_large:www \int_use:N \__int_eval:w \c__fp_leading_shift_int + #20 - #1*62831 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #30 - #1*8530 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_middle_shift_int + #40 - #1*7179 \exp_after:wN \__fp_pack:NNNNNw \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #50 - #1*5880 \exp_after:wN ; } \cs_new:Npn \__fp_trig_large_break:w \fi: #1; #2; { \fi: \__fp_trig_octant_loop:nnnnnw #2 {0000} {0000} ; } \cs_new:Npn \__fp_trig_octant_loop:nnnnnw #1#2#3#4#5#6; { \if_int_compare:w #1#2 < 157079633 \exp_stop_f: \if_int_compare:w #1#2 = 157079632 \exp_stop_f: \if_int_compare:w #3#4 > 67948969 \exp_stop_f: \use_i_ii:nnn \fi: \fi: \__fp_trig_octant_break:w \fi: + \c_two \__fp_fixed_sub:wwn {#1} {#2} {#3} {#4} {0000} {0000} ; {15707} {9632} {6794} {8970} {0000} {0000} ; \__fp_trig_octant_loop:nnnnnw } \cs_new:Npn \__fp_trig_octant_break:w #1 \fi: + #2#3 #4#5; #6; #7; { \fi: \if_int_compare:w #4 < 7854 \exp_stop_f: \exp_after:wN \__fp_use_i_until_s:nw \exp_after:wN . \fi: + \c_one \__fp_fixed_sub:wwn #6 ; {#4} #5 ; . ; } \cs_new:Npn \__fp_sin_series:NNwww #1#2#3 . #4; #5; { \__fp_fixed_mul:wwn #4; #4; { \exp_after:wN \__fp_sin_series_aux:NNnww \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} } #4 ; } \cs_new:Npn \__fp_sin_series_aux:NNnww #1#2#3 #4; #5; { \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}; } { % 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_fixed_mul:wwn #5; } { \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:NNwww #1#2#3. #4; #5; { \__fp_fixed_mul:wwn #4; #4; { \exp_after:wN \__fp_tan_series_aux_o:Nnww \__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} } #4 ; } \cs_new:Npn \__fp_tan_series_aux_o:Nnww #1 #2 #3; #4; { \__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_fixed_mul:wwn #4; { \__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}; { \exp_after:wN \__fp_sanitize:Nw \exp_after:wN #1 \int_use:N \__int_eval:w \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_fixed_div_to_float:ww } } } %% File: l3fp-convert.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_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:N \__int_value:w \etex_glueexpr:D #1 ; } \cs_new:Npn \__fp_from_dim_test:N #1 { \if_meaning:w 0 #1 \__fp_case_return:nw \c_zero_fp \else: \if_meaning:w - #1 \exp_after:wN \__fp_from_dim:Nw \exp_after:wN 2 \__int_value:w \else: \exp_after:wN \__fp_from_dim:Nw \exp_after:wN 0 \__int_value:w #1 \fi: \fi: } \cs_new:Npn \__fp_from_dim:Nw #1 #2; { \__fp_pack_twice_four:wNNNNNNNN \__fp_from_dim:wNNnnnnnn ; #2 000 0000 00 {10}987654321; #1 } \cs_new:Npn \__fp_from_dim:wNNnnnnnn #1; #2#3#4#5#6#7#8#9 { \__fp_from_dim:wnnnnwN #1 {#2#300} {0000} ; } \cs_new:Npn \__fp_from_dim:wnnnnwN #1; #2#3#4#5#6; #7 { \__fp_mul_npos_o:Nww #7 \s__fp \__fp_chk:w 1 #7 {#5} #1 ; \s__fp \__fp_chk:w 1 0 {-4} {1525} {8789} {0625} {0000} ; } \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-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_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 { \__fp_parse:n {#2} } } \cs_new_protected:Npn \fp_gset:Nn #1#2 { \tl_gset:Nx #1 { \__fp_parse:n {#2} } } \cs_new_protected:Npn \fp_const:Nn #1#2 { \tl_const:Nx #1 { \__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 9794 } \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'.