%%
%% This is file `l3fp.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% l3fp.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) 2010 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 ``expl3 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.
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
\GetIdInfo$Id: l3fp.dtx 1979 2010-07-08 19:51:19Z joseph $
  {L3 Experimental floating-point operations}
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
\int_new:N \l_fp_input_a_integer_int
\int_new:N \l_fp_input_a_decimal_int
\int_new:N \l_fp_input_b_integer_int
\int_new:N \l_fp_input_b_decimal_int
\int_new:N \l_fp_input_a_sign_int
\int_new:N \l_fp_input_b_sign_int
\int_new:N \l_fp_split_sign_int
\int_new:N \l_fp_mul_a_i_int
\int_new:N \l_fp_mul_a_ii_int
\int_new:N \l_fp_mul_a_iii_int
\int_new:N \l_fp_mul_a_iv_int
\int_new:N \l_fp_mul_a_v_int
\int_new:N \l_fp_mul_a_vi_int
\int_new:N \l_fp_mul_b_i_int
\int_new:N \l_fp_mul_b_ii_int
\int_new:N \l_fp_mul_b_iii_int
\int_new:N \l_fp_mul_b_iv_int
\int_new:N \l_fp_mul_b_v_int
\int_new:N \l_fp_mul_b_vi_int
\int_new:N \l_fp_mul_output_int
\tl_new:N  \l_fp_mul_output_tl
\int_new:N \l_fp_div_count_int
\int_new:N \l_fp_div_offset_int
\int_new:N \l_fp_output_sign_int
\int_new:N \l_fp_output_integer_int
\int_new:N \l_fp_output_decimal_int
\bool_new:N \l_fp_round_carry_bool
\tl_new:N \l_fp_round_decimal_tl
\int_new:N \l_fp_round_discard_int
\int_new:N \l_fp_round_position_int
\int_new:N \l_fp_tmp_int
\tl_new:N \l_fp_tmp_tl
\tl_new:N  \c_zero_fp
\tl_set:Nn \c_zero_fp { + 0.000000000 }
\tl_new:N  \c_undefined_fp
\tl_set:Nn \c_undefined_fp { X 0.000000000 }
\tl_new:N  \c_infinity_fp
\tl_set:Nn \c_infinity_fp { +2147483647.2147483647 }
\tl_new:N  \c_minus_infinity_fp
\tl_set:Nn \c_minus_infinity_fp { -2147483647.2147483647 }
\int_new:N  \c_one_hundred_million
\int_set:Nn \c_one_hundred_million  { 100000000 }
\int_new:N  \c_one_thousand_million
\int_set:Nn \c_one_thousand_million { 1000000000 }
\prg_new_conditional:Npnn \fp_if_infinite:N #1 { p , T , F , TF } {
  \tex_ifx:D #1 \c_infinity_fp
    \prg_return_true:
  \tex_else:D
    \tex_ifx:D #1 \c_minus_infinity_fp
      \prg_return_true:
    \tex_else:D
      \prg_return_false:
    \tex_fi:D
  \tex_fi:D
}
\prg_new_conditional:Npnn \fp_if_plus_infinity:N #1 { p , T , F , TF } {
  \tex_ifx:D #1 \c_infinity_fp
    \prg_return_true:
  \tex_else:D
    \prg_return_false:
  \tex_fi:D
}
\prg_new_conditional:Npnn \fp_if_minus_infinity:N #1 { p , T , F , TF }
  {
  \tex_ifx:D #1 \c_minus_infinity_fp
    \prg_return_true:
  \tex_else:D
    \prg_return_false:
  \tex_fi:D
}
\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF } {
  \tex_ifx:D #1 \c_undefined_fp
    \prg_return_true:
  \tex_else:D
    \prg_return_false:
  \tex_fi:D
}
\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF } {
  \tex_ifx:D #1 \c_zero_fp
    \prg_return_true:
  \tex_else:D
    \prg_return_false:
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_new:N #1 {
  \tl_new:N #1
  \tl_gset_eq:NN #1 \c_zero_fp
}
\cs_generate_variant:Nn \fp_new:N { c }
\cs_new_protected_nopar:Npn \fp_zero:N #1 {
  \tl_set_eq:NN #1 \c_zero_fp
}
\cs_new_protected_nopar:Npn \fp_gzero:N #1 {
  \tl_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_nopar:Npn \fp_set:Nn {
  \fp_set_aux:NNn \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gset:Nn {
  \fp_set_aux:NNn \tl_gset:Nn
}
\cs_new_protected_nopar:Npn \fp_set_aux:NNn #1#2#3 {
  \group_begin:
    \fp_split:Nn a {#3}
    \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
    \tl_set:Nx \l_fp_tmp_tl
      {
        \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
          -
        \tex_else:D
          +
        \tex_fi:D
        \int_use:N \l_fp_input_a_integer_int
        .
        \exp_after:wN \use_none:n
          \int_use:N \l_fp_input_a_decimal_int
      }
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_generate_variant:Nn \fp_set:Nn  { c }
\cs_generate_variant:Nn \fp_gset:Nn { c }
\cs_new_protected_nopar:Npn \fp_set_from_dim:Nn {
  \fp_set_from_dim_aux:NNn \tl_set:Nx
}
\cs_new_protected_nopar:Npn \fp_gset_from_dim:Nn {
  \fp_set_from_dim_aux:NNn \tl_gset:Nx
}
\cs_new_protected_nopar:Npn \fp_set_from_dim_aux:NNn #1#2#3 {
  \group_begin:
    \l_fp_tmp_dim \etex_dimexpr:D #3 \scan_stop:
    \fp_split:Nn a
      {
        \exp_after:wN \fp_set_from_dim_aux:w
          \dim_use:N \l_fp_tmp_dim
      }
    \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
    \tl_set:Nx \l_fp_tmp_tl
      {
        \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
          -
        \tex_else:D
          +
        \tex_fi:D
        \int_use:N \l_fp_input_a_integer_int
        .
        \exp_after:wN \use_none:n
          \int_use:N \l_fp_input_a_decimal_int
      }
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_set_protected_nopar:Npx \fp_set_from_dim_aux:w {
  \cs_set_nopar:Npn \exp_not:N \fp_set_from_dim_aux:w
    ##1 \tl_to_str:n { pt } {##1}
}
\fp_set_from_dim_aux:w
\cs_generate_variant:Nn \fp_set_from_dim:Nn  { c }
\cs_generate_variant:Nn \fp_gset_from_dim:Nn { c }
\dim_new:N \l_fp_tmp_dim
\cs_new_eq:NN \fp_set_eq:NN  \tl_set_eq:NN
\cs_new_eq:NN \fp_set_eq:cN  \tl_set_eq:cN
\cs_new_eq:NN \fp_set_eq:Nc  \tl_set_eq:Nc
\cs_new_eq:NN \fp_set_eq:cc  \tl_set_eq:cc
\cs_new_eq:NN \fp_gset_eq:NN \tl_gset_eq:NN
\cs_new_eq:NN \fp_gset_eq:cN \tl_gset_eq:cN
\cs_new_eq:NN \fp_gset_eq:Nc \tl_gset_eq:Nc
\cs_new_eq:NN \fp_gset_eq:cc \tl_gset_eq:cc
\cs_new_eq:NN \fp_show:N \tl_show:N
\cs_new_eq:NN \fp_show:c \tl_show:c
\cs_new_eq:NN \fp_use:N \tl_use:N
\cs_new_eq:NN \fp_use:c \tl_use:c
\cs_new_protected_nopar:Npn \fp_read:N #1 {
  \exp_after:wN \fp_read_aux:w #1 \q_stop
}
\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 \q_stop {
  \tex_if:D #1 -
    \l_fp_input_a_sign_int \c_minus_one
  \tex_else:D
    \l_fp_input_a_sign_int \c_one
  \tex_fi:D
  \l_fp_input_a_integer_int #2 \scan_stop:
  \l_fp_input_a_decimal_int #3 \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_split:Nn #1#2 {
  \tl_set:Nx \l_fp_tmp_tl {#2}
  \l_fp_split_sign_int \c_one
  \fp_split_sign:
  \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
  \tex_afterassignment:D \fp_split_aux_i:w
  \use:c { l_fp_input_ #1 _integer_int }
    \etex_numexpr:D 0 \l_fp_tmp_tl . . \q_stop #1
}
\cs_new_protected_nopar:Npn \fp_split_sign: {
  \tex_ifnum:D \pdf_strcmp:D
    { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { - }
      = \c_zero
    \tl_set:Nx \l_fp_tmp_tl
      {
        \exp_after:wN
          \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
      }
    \l_fp_split_sign_int -\l_fp_split_sign_int
    \exp_after:wN \fp_split_sign:
  \tex_else:D
    \tex_ifnum:D \pdf_strcmp:D
      { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { + }
        = \c_zero
      \tl_set:Nx \l_fp_tmp_tl
        {
          \exp_after:wN
            \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
        }
      \exp_after:wN \exp_after:wN \exp_after:wN
        \fp_split_sign:
     \tex_fi:D
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop {
  \fp_split_aux_ii:w #2 000000000 \q_stop
}
\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9 {
  \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9}
}
\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop {
  \l_fp_tmp_int 1 #1 \scan_stop:
  \exp_after:wN \fp_split_decimal:w
    \int_use:N \l_fp_tmp_int 000000000 \q_stop
}
\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9 {
  \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9}
}
\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4 {
  \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
  \tex_ifnum:D
    \etex_numexpr:D
      \use:c { l_fp_input_ #4 _integer_int } +
      \use:c { l_fp_input_ #4 _decimal_int }
    \scan_stop:
      = \c_zero
    \use:c { l_fp_input_ #4 _sign_int } \c_one
   \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_abs:N {
  \fp_abs:NN \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gabs:N {
  \fp_abs:NN \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_abs:N  { c }
\cs_generate_variant:Nn \fp_gabs:N { c }
\cs_new_protected_nopar:Npn \fp_abs:NN #1#2 {
  \group_begin:
    \fp_read:N #2
    \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
    \tl_set:Nx \l_fp_tmp_tl
      {
        +
        \int_use:N \l_fp_input_a_integer_int
        .
        \exp_after:wN \use_none:n
          \int_use:N \l_fp_input_a_decimal_int
      }
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_protected_nopar:Npn \fp_neg:N {
  \fp_neg_aux:NN \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gneg:N {
  \fp_neg_aux:NN \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_neg:N  { c }
\cs_generate_variant:Nn \fp_gneg:N { c }
\cs_new_protected_nopar:Npn \fp_neg_aux:NN #1#2 {
  \group_begin:
    \fp_read:N #2
    \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
    \tl_set:Nx \l_fp_tmp_tl
      {
        \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
          +
        \tex_else:D
          -
        \tex_fi:D
        \int_use:N \l_fp_input_a_integer_int
        .
        \exp_after:wN \use_none:n
          \int_use:N \l_fp_input_a_decimal_int
      }
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_protected_nopar:Npn \fp_add:Nn {
  \fp_add_aux:NNn \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gadd:Nn {
  \fp_add_aux:NNn \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_add:Nn   { c }
\cs_generate_variant:Nn \fp_gadd:Nn  { c }
\cs_new_protected_nopar:Npn \fp_add_aux:NNn #1#2#3 {
  \group_begin:
    \fp_read:N #2
    \fp_split:Nn b {#3}
    \fp_add_core:
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_protected_nopar:Npn \fp_add_core: {
  \tex_ifnum:D
    \etex_numexpr:D
      \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
    \scan_stop:
      > \c_zero
    \exp_after:wN \fp_add_sum:
  \tex_else:D
    \exp_after:wN \fp_add_difference:
  \tex_fi:D
  \tl_set:Nx \l_fp_tmp_tl
    {
      \tex_ifnum:D \l_fp_output_sign_int < \c_zero
        -
      \tex_else:D
        +
      \tex_fi:D
      \int_use:N \l_fp_output_integer_int
      .
      \exp_after:wN \use_none:n
        \int_use:N \l_fp_output_decimal_int
    }
}
\cs_new_protected_nopar:Npn \fp_add_sum: {
  \l_fp_output_sign_int \l_fp_input_a_sign_int
  \l_fp_output_integer_int
    \etex_numexpr:D
      \l_fp_input_a_integer_int + \l_fp_input_b_integer_int
    \scan_stop:
  \l_fp_output_decimal_int
    \etex_numexpr:D
      \l_fp_input_a_decimal_int + \l_fp_input_b_decimal_int
    \scan_stop:
  \tex_ifnum:D \l_fp_output_decimal_int < \c_one_thousand_million
    \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
  \tex_else:D
    \tex_advance:D \l_fp_output_integer_int \c_one
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_add_difference: {
  \l_fp_output_integer_int
    \etex_numexpr:D
      \l_fp_input_a_integer_int - \l_fp_input_b_integer_int
    \scan_stop:
  \l_fp_output_decimal_int
    \etex_numexpr:D
      \l_fp_input_a_decimal_int - \l_fp_input_b_decimal_int
    \scan_stop:
  \tex_ifnum:D \l_fp_output_decimal_int < \c_zero
    \tex_advance:D \l_fp_output_integer_int \c_minus_one
    \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
  \tex_fi:D
  \tex_ifnum:D \l_fp_output_integer_int < \c_zero
    \l_fp_output_sign_int \l_fp_input_b_sign_int
    \tex_ifnum:D \l_fp_output_decimal_int = \c_zero
      \l_fp_output_integer_int -\l_fp_output_integer_int
    \tex_else:D
      \l_fp_output_decimal_int
        \etex_numexpr:D
          \c_one_thousand_million - \l_fp_output_decimal_int
        \scan_stop:
      \l_fp_output_integer_int
         \etex_numexpr:D
           - \l_fp_output_integer_int - \c_one
         \scan_stop:
    \tex_fi:D
  \tex_else:D
    \l_fp_output_sign_int \l_fp_input_a_sign_int
  \tex_fi:D
  \tex_ifnum:D
    \etex_numexpr:D
      \l_fp_output_integer_int + \l_fp_output_decimal_int
    \scan_stop:
      = \c_zero
    \l_fp_output_sign_int \c_one
  \tex_fi:D
  \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
}
\cs_new_protected_nopar:Npn \fp_sub:Nn {
  \fp_sub_aux:NNn \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gsub:Nn {
  \fp_sub_aux:NNn \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_sub:Nn   { c }
\cs_generate_variant:Nn \fp_gsub:Nn  { c }
\cs_new_protected_nopar:Npn \fp_sub_aux:NNn #1#2#3 {
  \group_begin:
    \fp_read:N #2
    \fp_split:Nn b {#3}
    \tex_multiply:D \l_fp_input_b_sign_int \c_minus_one
    \fp_add_core:
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_protected_nopar:Npn \fp_mul:Nn {
  \fp_mul_aux:NNn \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gmul:Nn {
  \fp_mul_aux:NNn \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_mul:Nn  { c }
\cs_generate_variant:Nn \fp_gmul:Nn { c }
\cs_new_protected_nopar:Npn \fp_mul_aux:NNn #1#2#3 {
  \group_begin:
    \fp_read:N #2
    \fp_split:Nn b {#3}
    \fp_mul_split:NNNN \l_fp_input_a_integer_int
      \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
    \fp_mul_split:NNNN \l_fp_input_a_decimal_int
      \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
    \fp_mul_split:NNNN \l_fp_input_b_integer_int
      \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
    \fp_mul_split:NNNN \l_fp_input_b_decimal_int
      \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
    \l_fp_mul_output_int \c_zero
    \tl_clear:N \l_fp_mul_output_tl
    \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_vi_int
    \fp_mul_product:NN \l_fp_mul_a_v_int  \l_fp_mul_b_v_int
    \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_iv_int
    \tex_divide:D \l_fp_mul_output_int \c_thousand
    \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_vi_int
    \fp_mul_product:NN \l_fp_mul_a_iv_int  \l_fp_mul_b_v_int
    \fp_mul_product:NN \l_fp_mul_a_v_int   \l_fp_mul_b_iv_int
    \fp_mul_product:NN \l_fp_mul_a_vi_int  \l_fp_mul_b_iii_int
    \fp_mul_end_level:
    \fp_mul_product:NN \l_fp_mul_a_ii_int  \l_fp_mul_b_vi_int
    \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_v_int
    \fp_mul_product:NN \l_fp_mul_a_iv_int  \l_fp_mul_b_iv_int
    \fp_mul_product:NN \l_fp_mul_a_v_int   \l_fp_mul_b_iii_int
    \fp_mul_product:NN \l_fp_mul_a_vi_int  \l_fp_mul_b_ii_int
    \fp_mul_end_level:
    \fp_mul_product:NN \l_fp_mul_a_i_int   \l_fp_mul_b_vi_int
    \fp_mul_product:NN \l_fp_mul_a_ii_int  \l_fp_mul_b_v_int
    \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
    \fp_mul_product:NN \l_fp_mul_a_iv_int  \l_fp_mul_b_iii_int
    \fp_mul_product:NN \l_fp_mul_a_v_int   \l_fp_mul_b_ii_int
    \fp_mul_product:NN \l_fp_mul_a_vi_int  \l_fp_mul_b_i_int
    \fp_mul_end_level:
    \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
    \tl_clear:N \l_fp_mul_output_tl
    \fp_mul_product:NN \l_fp_mul_a_i_int   \l_fp_mul_b_v_int
    \fp_mul_product:NN \l_fp_mul_a_ii_int  \l_fp_mul_b_iv_int
    \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
    \fp_mul_product:NN \l_fp_mul_a_iv_int  \l_fp_mul_b_ii_int
    \fp_mul_product:NN \l_fp_mul_a_v_int   \l_fp_mul_b_i_int
    \fp_mul_end_level:
    \fp_mul_product:NN \l_fp_mul_a_i_int   \l_fp_mul_b_iv_int
    \fp_mul_product:NN \l_fp_mul_a_ii_int  \l_fp_mul_b_iii_int
    \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
    \fp_mul_product:NN \l_fp_mul_a_iv_int  \l_fp_mul_b_i_int
    \fp_mul_end_level:
    \fp_mul_product:NN \l_fp_mul_a_i_int   \l_fp_mul_b_iii_int
    \fp_mul_product:NN \l_fp_mul_a_ii_int  \l_fp_mul_b_ii_int
    \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
    \fp_mul_end_level:
    \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
    \tl_clear:N \l_fp_mul_output_tl
    \fp_mul_product:NN \l_fp_mul_a_i_int   \l_fp_mul_b_ii_int
    \fp_mul_product:NN \l_fp_mul_a_ii_int  \l_fp_mul_b_i_int
    \fp_mul_end_level:
    \fp_mul_product:NN \l_fp_mul_a_i_int   \l_fp_mul_b_i_int
    \fp_mul_end_level:
    \tex_ifnum:D \l_fp_mul_output_tl = \c_zero
    \tex_else:D
      \exp_after:wN \fp_msg_overflow:
    \tex_fi:D
    \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
    \tl_set:Nx \l_fp_tmp_tl
      {
        \tex_ifnum:D
          \etex_numexpr:D
            \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
          \scan_stop:
            < \c_zero
          \tex_ifnum:D
            \etex_numexpr:D
              \l_fp_output_integer_int + \l_fp_output_decimal_int
            \scan_stop:
              = \c_one_thousand_million
            +
          \tex_else:D
            -
          \tex_fi:D
        \tex_else:D
          +
        \tex_fi:D
        \int_use:N \l_fp_output_integer_int
        .
        \exp_after:wN \use_none:n
          \int_use:N \l_fp_output_decimal_int
      }
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_protected_nopar:Npn \fp_mul_split:NNNN #1#2#3#4 {
  \tex_advance:D #1 \c_one_thousand_million
  \cs_set_protected_nopar:Npn \fp_mul_split_aux:w
    ##1##2##3##4##5##6##7##8##9 \q_stop {
      #2 ##2##3##4 \scan_stop:
      #3 ##5##6##7 \scan_stop:
      #4 ##8##9    \scan_stop:
    }
  \exp_after:wN \fp_mul_split_aux:w \int_use:N #1 \q_stop
}
\cs_new_protected_nopar:Npn \fp_mul_product:NN #1#2 {
  \l_fp_mul_output_int
    \etex_numexpr:D \l_fp_mul_output_int + #1 * #2 \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_mul_end_level: {
  \tex_advance:D \l_fp_mul_output_int \c_one_thousand_million
  \exp_after:wN \fp_mul_end_level:w
    \int_use:N \l_fp_mul_output_int \q_stop
}
\cs_new_protected_nopar:Npn \fp_mul_end_level:w
  #1#2#3#4#5#6#7#8#9 \q_stop {
  \tl_set:Nx \l_fp_mul_output_tl { #8#9 \l_fp_mul_output_tl }
  \l_fp_mul_output_int #5#6#7 \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_div:Nn {
  \fp_div_aux:NNn \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gdiv:Nn {
  \fp_div_aux:NNn \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_div:Nn  { c }
\cs_generate_variant:Nn \fp_gdiv:Nn { c }

\cs_new_protected_nopar:Npn \fp_div_aux:NNn #1#2#3 {
  \group_begin:
    \fp_read:N #2
    \fp_split:Nn b {#3}
    \tex_ifnum:D
      \etex_numexpr:D
        \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
      \scan_stop:
        = \c_zero
      \tl_set_eq:NN \l_fp_tmp_tl \c_undefined_fp
    \tex_else:D
      \tex_ifnum:D
        \etex_numexpr:D
          \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
        \scan_stop:
          = \c_zero
          \tl_set_eq:NN \l_fp_tmp_tl \c_zero_fp
      \tex_else:D
        \exp_after:wN \exp_after:wN \exp_after:wN
          \fp_div_aux:
      \tex_fi:D
    \tex_fi:D
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_protected_nopar:Npn \fp_div_aux: {
  \l_fp_div_offset_int \c_one
  \tex_ifnum:D \l_fp_input_a_integer_int > \c_zero
    \exp_after:wN \fp_div_offset_create:
  \tex_fi:D
  \l_fp_output_integer_int \c_zero
  \l_fp_output_decimal_int \c_one_thousand_million
  \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
  \fp_div_loop:
  \tl_set:Nx \l_fp_tmp_tl
    {
      \tex_ifnum:D
        \etex_numexpr:D
          \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
        \scan_stop:
          < \c_zero
        \tex_ifnum:D
          \etex_numexpr:D
            \l_fp_output_integer_int + \l_fp_output_decimal_int
          \scan_stop:
            = \c_one_thousand_million
          +
        \tex_else:D
          -
        \tex_fi:D
      \tex_else:D
        +
      \tex_fi:D
      \int_use:N \l_fp_output_integer_int
      .
      \exp_after:wN \use_none:n
        \int_use:N \l_fp_output_decimal_int
    }
}
\cs_new_protected_nopar:Npn \fp_div_offset_create: {
  \tex_ifnum:D \l_fp_input_b_integer_int = \c_zero
    \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
    \exp_after:wN \fp_div_offset_create_aux:w
      \int_use:N \l_fp_input_b_decimal_int \q_stop
    \exp_after:wN \fp_div_offset_create:
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_div_offset_create_aux:w
  #1#2#3#4#5#6#7#8#9 \q_stop {
  \l_fp_input_b_integer_int #2 \scan_stop:
  \l_fp_input_b_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
  \tex_multiply:D \l_fp_div_offset_int \c_ten
}
\cs_new_protected_nopar:Npn \fp_div_loop: {
  \l_fp_div_count_int \c_zero
  \fp_div_divide:
  \tex_divide:D \l_fp_input_b_decimal_int \c_ten
  \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
  \exp_after:wN \fp_div_loop_aux_i:w
    \int_use:N \l_fp_input_b_integer_int
  \fp_div_store:
  \tex_ifnum:D
    \etex_numexpr:D
      \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
      > \c_zero
    \tex_ifnum:D
      \etex_numexpr:D
        \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
        > \c_zero
      \exp_after:wN \exp_after:wN \exp_after:wN
        \fp_div_loop:
    \tex_fi:D
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_div_divide: {
  \tex_ifnum:D \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
    \exp_after:wN \fp_div_divide_aux:
  \tex_else:D
    \tex_ifnum:D \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
    \tex_else:D
      \tex_ifnum:D
        \l_fp_input_a_decimal_int < \l_fp_input_b_decimal_int
      \tex_else:D
        \exp_after:wN \exp_after:wN \exp_after:wN
          \exp_after:wN \exp_after:wN \exp_after:wN
          \exp_after:wN \fp_div_divide_aux:
      \tex_fi:D
    \tex_fi:D
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_div_loop_aux_i:w #1#2#3#4#5#6#7#8#9 {
  \fp_div_loop_aux_ii:w #2#3#4#5#6#7#8#9
}
\cs_new_protected_nopar:Npn \fp_div_loop_aux_ii:w #1#2#3#4#5#6#7#8#9 {
  \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
  \l_fp_input_b_decimal_int
    \etex_numexpr:D
      \l_fp_input_b_decimal_int + \c_one_hundred_million * #9
    \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_div_divide_aux: {
  \tex_advance:D \l_fp_div_count_int \c_one
  \tex_advance:D \l_fp_input_a_integer_int -\l_fp_input_b_integer_int
  \tex_advance:D \l_fp_input_a_decimal_int -\l_fp_input_b_decimal_int
  \tex_ifnum:D \l_fp_input_a_decimal_int < \c_zero
    \tex_advance:D \l_fp_input_a_integer_int \c_minus_one
    \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
  \tex_fi:D
  \fp_div_divide:
}
\cs_new_protected_nopar:Npn \fp_div_store: { }
\cs_new_protected_nopar:Npn \fp_div_store_integer: {
  \l_fp_output_integer_int
    \etex_numexpr:D
      \l_fp_output_integer_int +
      \l_fp_div_count_int * \l_fp_div_offset_int
    \scan_stop:
  \tex_ifnum:D \l_fp_div_offset_int > \c_one
    \tex_divide:D \l_fp_div_offset_int \c_ten
  \tex_else:D
    \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
    \l_fp_div_offset_int \c_one_hundred_million
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_div_store_decimal: {
  \l_fp_output_decimal_int
    \etex_numexpr:D
      \l_fp_output_decimal_int +
      \l_fp_div_count_int * \l_fp_div_offset_int
    \scan_stop:
  \tex_divide:D \l_fp_div_offset_int \c_ten
}
\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3
  { T , F , TF } {
  \group_begin:
    \fp_split:Nn a {#1}
    \fp_split:Nn b {#3}
    \fp_compare_aux:N #2
}
\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3
  { T , F , TF } {
  \group_begin:
    \fp_read:N #3
    \l_fp_input_b_sign_int \l_fp_input_a_sign_int
    \l_fp_input_b_integer_int \l_fp_input_a_integer_int
    \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
    \fp_read:N #1
    \fp_compare_aux:N #2
}
\cs_new_protected_nopar:Npn \fp_compare_aux:N #1 {
  \cs_if_exist:cTF { fp_compare_#1: }
    { \use:c { fp_compare_#1: } }
    {
      \group_end:
      \prg_return_false:
    }
}
\cs_new_protected_nopar:cpn { fp_compare_=: } {
  \tex_ifnum:D \l_fp_input_a_sign_int = \l_fp_input_b_sign_int
    \tex_ifnum:D \l_fp_input_a_integer_int = \l_fp_input_b_integer_int
      \tex_ifnum:D \l_fp_input_a_decimal_int = \l_fp_input_b_decimal_int
        \group_end:
        \prg_return_true:
      \tex_else:D
        \group_end:
        \prg_return_false:
      \tex_fi:D
    \tex_else:D
      \group_end:
      \prg_return_false:
    \tex_fi:D
  \tex_else:D
    \group_end:
    \prg_return_false:
  \tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_>: } {
  \tex_ifnum:D \l_fp_input_a_sign_int > \l_fp_input_b_sign_int
    \group_end:
    \prg_return_true:
  \tex_else:D
    \tex_ifnum:D \l_fp_input_a_sign_int < \l_fp_input_b_sign_int
      \group_end:
      \prg_return_false:
    \tex_else:D
      \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
        \use:c { fp_compare_absolute_a > b: }
      \tex_else:D
        \use:c { fp_compare_absolute_a < b: }
      \tex_fi:D
    \tex_fi:D
  \tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_<: } {
  \tex_ifnum:D \l_fp_input_b_sign_int > \l_fp_input_a_sign_int
    \group_end:
    \prg_return_true:
  \tex_else:D
    \tex_ifnum:D \l_fp_input_b_sign_int < \l_fp_input_a_sign_int
      \group_end:
      \prg_return_false:
    \tex_else:D
      \tex_ifnum:D \l_fp_input_b_sign_int > \c_zero
        \use:c { fp_compare_absolute_a < b: }
      \tex_else:D
        \use:c { fp_compare_absolute_a > b: }
      \tex_fi:D
    \tex_fi:D
  \tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_absolute_a > b: } {
  \tex_ifnum:D \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
    \group_end:
    \prg_return_true:
  \tex_else:D
    \tex_ifnum:D \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
      \group_end:
      \prg_return_false:
    \tex_else:D
      \tex_ifnum:D \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
        \group_end:
        \prg_return_true:
      \tex_else:D
        \group_end:
        \prg_return_false:
      \tex_fi:D
    \tex_fi:D
  \tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_absolute_a < b: } {
  \tex_ifnum:D \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
    \group_end:
    \prg_return_true:
  \tex_else:D
    \tex_ifnum:D \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
      \group_end:
      \prg_return_false:
    \tex_else:D
      \tex_ifnum:D \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
        \group_end:
        \prg_return_true:
      \tex_else:D
        \group_end:
        \prg_return_false:
      \tex_fi:D
    \tex_fi:D
  \tex_fi:D
}
\keys_define:nn { fp } {
  precision             .int_set:N  = \l_fp_round_precision_int ,
  remove-trailing-zeros .bool_set:N = \l_fp_remove_zeros_bool   ,
  round-mode            .choice:                                ,
  round-mode
    / half-even         .tl_set:N   = \l_fp_round_mode_tl       ,
  round-mode
    / half-from-zero    .tl_set:N   = \l_fp_round_mode_tl       ,
  round-mode
    / none              .tl_set:N   = \l_fp_round_mode_tl       ,
  round-mode
    / truncate          .tl_set:N   = \l_fp_round_mode_tl       ,
}
\keys_set:nn { fp } {
  precision             = 9    ,
  remove-trailing-zeros = true ,
  round-mode            = none ,
}
\cs_new_protected_nopar:Npn \fp_to_tl:NN {
  \fp_to_tl_aux:NNN \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gto_tl:NN {
  \fp_to_tl_aux:NNN \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_to_tl:NN  { Nc }
\cs_generate_variant:Nn \fp_to_tl:NN  { c }
\cs_generate_variant:Nn \fp_to_tl:NN  { cc }
\cs_generate_variant:Nn \fp_gto_tl:NN { Nc }
\cs_generate_variant:Nn \fp_gto_tl:NN { c }
\cs_generate_variant:Nn \fp_gto_tl:NN { cc }
\cs_new_protected_nopar:Npn \fp_to_tl_aux:NNN #1#2#3 {
  \group_begin:
    \fp_read:N #2
    \use:c { fp_round_ \l_fp_round_mode_tl :}
    \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
    \tl_set:Nx \l_fp_tmp_tl
      {
        \tex_ifnum:D  \l_fp_input_a_sign_int < \c_zero
          -
        \tex_fi:D
        \int_use:N \l_fp_input_a_integer_int
        \intexpr_compare:nNnT { \l_fp_round_precision_int } > { \c_zero }
          {
            .
            \bool_if:NTF \l_fp_remove_zeros_bool
              {
                \exp_after:wN \use_i:nn
                  \exp_after:wN \fp_remove_zeros:NNNNNNNNN
              }
              { \exp_after:wN \use_none:n }
            \int_use:N \l_fp_input_a_decimal_int
          }
      }
  \exp_after:wN \group_end: \exp_after:wN
  #1 \exp_after:wN #3 \exp_after:wN { \l_fp_tmp_tl }
}
\cs_new_nopar:Npn \fp_remove_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
  \fp_remove_zeros_aux:w #1#2#3#4#5#6#7#8#9 \q_stop 1
}
\cs_new_nopar:Npn \fp_remove_zeros_aux:w #1#2 \q_stop #3 {
  #1
  \intexpr_compare:nNnTF { 0 #2 } = { \c_zero }
    {
      \intexpr_compare:nNnF { \l_fp_round_precision_int } < { #3 + 1 }
        {
          \intexpr_compare:nNnT {#3} < { 9 }
            { \fp_remove_zeros_aux:w #2 \q_stop { #3 + 1 } }
        }
    }
    {
      \intexpr_compare:nNnT {#3} < { 9 }
        { \fp_remove_zeros_aux:w #2 \q_stop { #3 + 1 } }
    }
}
\cs_new_protected_nopar:cpn { fp_round_half-from-zero: } {
  \tex_ifnum:D \l_fp_round_precision_int < \c_nine
    \exp_after:wN \fp_round_from_zero:
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_round_from_zero: {
  \bool_set_false:N \l_fp_round_carry_bool
  \l_fp_round_position_int \c_eight
  \tl_clear:N \l_fp_round_decimal_tl
  \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
  \exp_after:wN \use_i:nn \exp_after:wN
    \fp_round_from_zero_aux:NNNNNNNNN
    \int_use:N \l_fp_input_a_decimal_int
}
\cs_new_protected_nopar:Npn \fp_round_from_zero_aux:NNNNNNNNN
  #1#2#3#4#5#6#7#8#9 {
  \fp_round_from_zero_decimal:N #9#8#7#6#5#4#3#2#1
  \fp_round_from_zero_integer:
}
\cs_new_protected_nopar:Npn \fp_round_from_zero_decimal:N #1 {
  \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_precision_int
    \bool_if:NTF \l_fp_round_carry_bool
      { \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop: }
      { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
    \tex_ifnum:D \l_fp_tmp_int = \c_ten
      \l_fp_tmp_int \c_zero
    \tex_else:D
      \bool_set_false:N \l_fp_round_carry_bool
    \tex_fi:D
    \tl_set:Nx \l_fp_round_decimal_tl
      { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
  \tex_else:D
    \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
    \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_precision_int
      \tex_ifnum:D #1 > \c_four
        \bool_set_true:N \l_fp_round_carry_bool
      \tex_fi:D
    \tex_fi:D
  \tex_fi:D
  \tex_advance:D \l_fp_round_position_int \c_minus_one
  \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
    \exp_after:wN \fp_round_from_zero_decimal:N
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_round_from_zero_integer: {
  \bool_if:NT \l_fp_round_carry_bool
    { \tex_advance:D \l_fp_input_a_integer_int \c_one }
  \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
}
\cs_new_protected_nopar:cpn { fp_round_half-even: } {
  \tex_ifnum:D \l_fp_round_precision_int < \c_nine
    \exp_after:wN \fp_round_even:
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_round_even: {
  \bool_set_false:N \l_fp_round_carry_bool
  \l_fp_round_position_int \c_eight
  \tl_clear:N \l_fp_round_decimal_tl
  \int_zero:N \l_fp_round_discard_int
  \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
  \exp_after:wN \use_i:nn \exp_after:wN
    \fp_round_even_aux:NNNNNNNNN
    \int_use:N \l_fp_input_a_decimal_int
}
\cs_new_protected_nopar:Npn \fp_round_even_aux:NNNNNNNNN
  #1#2#3#4#5#6#7#8#9 {
  \fp_round_even_decimal:N #9#8#7#6#5#4#3#2#1
  \fp_round_even_integer:
}
\cs_new_protected_nopar:Npn \fp_round_even_decimal:N #1 {
  \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_precision_int
    \bool_if:NTF \l_fp_round_carry_bool
      {
        \tex_ifnum:D \l_fp_round_discard_int = \c_zero
          \l_fp_round_discard_int \c_one
          \tex_ifodd:D #1 \scan_stop:
            \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop:
          \tex_else:D
            \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop:
          \tex_fi:D
        \tex_else:D
          \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop:
        \tex_fi:D
      }
      { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
    \tex_ifnum:D \l_fp_tmp_int = \c_ten
      \l_fp_tmp_int \c_zero
    \tex_else:D
      \bool_set_false:N \l_fp_round_carry_bool
    \tex_fi:D
    \tl_set:Nx \l_fp_round_decimal_tl
      { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
  \tex_else:D
    \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
    \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_precision_int
      \tex_ifnum:D #1 > \c_four
        \bool_set_true:N \l_fp_round_carry_bool
        \tex_ifnum:D #1 = \c_five
        \tex_else:D
          \l_fp_round_discard_int \c_one
        \tex_fi:D
      \tex_fi:D
    \tex_else:D
      \tex_advance:D \l_fp_round_discard_int #1 \scan_stop:
    \tex_fi:D
  \tex_fi:D
  \tex_advance:D \l_fp_round_position_int \c_minus_one
  \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
    \exp_after:wN \fp_round_even_decimal:N
  \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_round_even_integer: {
  \bool_if:NT \l_fp_round_carry_bool
    {
      \tex_ifnum:D \l_fp_round_discard_int = \c_zero
        \tex_ifodd:D \l_fp_input_a_integer_int
          \tex_advance:D \l_fp_input_a_integer_int \c_one
        \tex_fi:D
      \tex_else:D
        \tex_advance:D \l_fp_input_a_integer_int \c_one
      \tex_fi:D
    }
  \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_round_none: {
  \l_fp_round_precision_int \c_one
}
\cs_new_protected_nopar:Npn \fp_round_truncate: {
  \intexpr_compare:nNnF { \l_fp_round_precision_int } > { 8 }
    {
      \intexpr_compare:nNnTF { \l_fp_round_precision_int } < { 1 }
        { \l_fp_input_a_decimal_int \c_zero \scan_stop: }
        {
          \int_set:Nn \l_fp_tmp_int
            {
              \prg_replicate:nn { 9 - \l_fp_round_precision_int }
                { 10 * }
              1
            }
          \tex_divide:D \l_fp_input_a_decimal_int \l_fp_tmp_int
          \tex_multiply:D \l_fp_input_a_decimal_int \l_fp_tmp_int
        }
    }
}
\cs_new_protected_nopar:Npn \fp_msg_overflow: {
  \msg_kernel_error:nn { fpu } { overflow }
}
\msg_kernel_new:nnnn { fpu } { overflow }
  { Arithmetic~overflow. }
  {
    The~calculation~requested~exceeds~the~capacity \\
    of~the~fixed-point~unit.
  }
%% 
%%
%% End of file `l3fp.sty'.
