试图

试图

因此,我必须使用英制和公制单位进行大量计算。我正在寻找一种以 SI 形式存储值的方法

  • 一个想法就是以这样一种方式定义,\storeval{name}{quantity}{unit}以便于检索name数量和单位。任何沿着\unit{name}\value{name}\unitSI{name}的语法\valueSI{name}都很好。例子。设\storeval{boatspeed}{25}{kts}(结) 然后\value{boatspeed}=25\unit{boatspeed}=kts和。\unitSI{boatspeed}=m/s\unitSI{boatspeed}=12.8611
  • 作为奖励,使用这些单位进行一些简单的计算会很好。例如,如果\storeval{boatspeed}{25}{kts}和,\storeval{distanceShore}{3}{nmi} 我有兴趣将值和单位以公制(SI 单位)存储distanceShore/boatspeed在新变量中\storeval

试图

\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}


\ExplSyntaxOn

\NewDocumentCommand{\setfpvar}{mm}
 {
  \fp_zero_new:c { nebu_var_#1_fp }
  \fp_set:cn { nebu_var_#1_fp } { #2 }
 }

\NewExpandableDocumentCommand{\fv}{m}
 {
  \fp_use:c { nebu_var_#1_fp }
 }

% make an internal function available to the user
\cs_set_eq:NN \fpeval \fp_eval:n

\msg_new:nnn
  { switchcase }
  { no-match }
  { There~is~no~entry~`#1'~in~the~switch~statement! }

\NewDocumentCommand \switchcase { m m }
  {
    \str_case:nnF { #1 } { #2 } { \msg_error:nnn { switchcase } { no-match } { #1 } }
  }
  
\cs_set_eq:NN \IfEmptyTF \tl_if_blank:nTF

\NewDocumentCommand{\impIIsi}{m G{}}{
    \IfEmptyTF{#2}%
            {\unitIIsi{#1}}%
            {\valueIIsi{#1}{#2}}%
}

\NewExpandableDocumentCommand{\valueIIsi}{m m}{
  \switchcase{#2}%
  {
    % Distances
    {cm}{\fpeval{#1/1000}} % centimeters
    {m}{#1}
    {km}{\fpeval{1000*#1}} % kilometers
    {feet}{\fpeval{0.3048*#1}}
    {ft}{\fpeval{0.3048*#1}}
    {mi}{\fpeval{1609*#1}} % english miles
    {M}{\fpeval{1852*#1}}  % nautical miles
    {NM}{\fpeval{1852*#1}} % nautical miles
    {nmi}{\fpeval{1852*#1}} % nautical miles
    {au}{\fpeval{149597870700*#1}} % astronomical unit
    %
    % Time
    {s}{#1} % 
    {sec}{#1} % 
    {d}{\fpeval{86400*#1}}
    {day}{\fpeval{86400*#1}}
    {min}{\fpeval{3600*#1}} % minute
    {h}{\fpeval{3600*#1}} % hour
    %
    % Weight
    {Da}{\fpeval{1.66053906660*10^(−27)*#1}}
    {t}{\fpeval{10^(3)*#1}} % tonne
    {lb}{\fpeval{0.45359237*#1}}
    {slug}{\fpeval{14.59390*#1}}
    %
    % Temperature
    {celcius}{\fpeval{#1+273}}
    {C}{\fpeval{#1+273}}
    {farenheit}{\fpeval{(#1-32)*(5/9)+273}}
    {F}{\fpeval{(#1-32)*(5/9)+273}}
  }%
}

\NewExpandableDocumentCommand{\unitIIsi}{m}{
  \switchcase{#1}%
  {
    {cm}{m}
    {m}{m}
    {km}{m}
    {mi}{m}
    {M}{m}
    {NM}{m}
    {nmi}{m}
  }%
}

\ExplSyntaxOff

\DeclareSIUnit\lbf{lbf}

\begin{document}

\setfpvar{boatlength}{5} % Saves the value 0.87 nautical miles in meters

\setfpvar{boatweightLBF}{1}
\setfpvar{boatweight}{%
  \fv{boatweightLBF}*\valueIIsi{1}{ft}*\valueIIsi{1}{lb}/\valueIIsi{1}{s}^2
}
\setfpvar{boatArea}{%
  (\valueIIsi{100}{ft})^2
}
\setfpvar{pressureOnWater}{%
  \fv{boatweight}/\fv{boatArea}
}

The weight of the boat is 
\SI{\fv{boatweightLBF}}{\lbf} or \SI{\fv{boatweight}}{\newton}

\end{document}

答案1

看一下这个框架。

\documentclass{article}
\usepackage{xparse}
\usepackage{expl3}

\ExplSyntaxOn

% functions to do numerical conversion
\cs_set:cpn {uconv_func_ft_m} #1 {
    \fp_eval:n {#1 / 3.2808}
}

\cs_set:cpn {uconv_func_km/s_m/s} #1 {
    \fp_eval:n {#1 / 3.6}
}

\prop_new:N \g_uconv_var_prop

% conversion between non-SI units to SI
\prop_new:N \g_uconv_unit_to_si_prop
\prop_gset_from_keyval:Nn \g_uconv_unit_to_si_prop {
    ft=m,
    km/s=m/s
}

\newcommand{\storeval}[3]{
    \prop_gput:Nnn \g_uconv_var_prop {#1} {{#2}{#3}}
}

\tl_new:N \l_uconv_tmpa_tl
\tl_new:N \l_uconv_tmpb_tl
\tl_new:N \l_uconv_tmpc_tl
\tl_new:N \l_uconv_tmpd_tl
\tl_new:N \l_uconv_tmpe_tl
\tl_new:N \l_uconv_tmpf_tl
\tl_new:N \l_uconv_tmpg_tl
\tl_new:N \l_uconv_unit_si_tl

\newcommand{\getval}[1]{
    \prop_get:NnNTF \g_uconv_var_prop {#1} \l_uconv_tmpa_tl {
        \tl_item:Nn \l_uconv_tmpa_tl {1}
    } {
        \GenericError{}{unable~to ~fetch~variable~#1}{}{}
    }
}

\newcommand{\getunit}[1]{
    \prop_get:NnNTF \g_uconv_var_prop {#1} \l_uconv_tmpa_tl {
        \tl_item:Nn \l_uconv_tmpa_tl {2}
    } {
        \GenericError{}{unable~to ~fetch~variable~#1}{}{}
    }
}

\cs_set:Npn \uconv_fetch_unit_si:n #1 {
    \prop_get:NnNF \g_uconv_unit_to_si_prop {#1} \l_uconv_unit_si_tl {
        % if the unit to SI conversion cannot be found
        % assume the unit itself is already SI
        \tl_set:Nn \l_uconv_unit_si_tl {#1}
    }
}

\newcommand{\getunitSI}[1]{
    \prop_get:NnNTF \g_uconv_var_prop {#1} \l_uconv_tmpa_tl {
        \tl_set:Nx \l_uconv_tmpb_tl {\tl_item:Nn \l_uconv_tmpa_tl {2}}
        \exp_args:NV \uconv_fetch_unit_si:n \l_uconv_tmpb_tl
        \tl_use:N \l_uconv_unit_si_tl
    } {
        \GenericError{}{unable~to~fetch~variable~#1}{}{}
    }
}

\newcommand{\getvalSI}[1]{
    \prop_get:NnNTF \g_uconv_var_prop {#1} \l_uconv_tmpd_tl {
        \tl_set:Nx \l_uconv_tmpe_tl {\tl_item:Nn \l_uconv_tmpd_tl {1}}
        \tl_set:Nx \l_uconv_tmpf_tl {\tl_item:Nn \l_uconv_tmpd_tl {2}}
        \exp_args:NV \uconv_fetch_unit_si:n \l_uconv_tmpf_tl
        \tl_if_eq:NNTF \l_uconv_tmpf_tl \l_uconv_unit_si_tl {
            % do not convert if both are the same
            \tl_use:N \l_uconv_tmpe_tl
        } {
            \cs_if_exist:cTF {uconv_func_ \l_uconv_tmpf_tl _\l_uconv_unit_si_tl} {
                \use:c {uconv_func_ \l_uconv_tmpf_tl _\l_uconv_unit_si_tl} \l_uconv_tmpe_tl
            } {
                \GenericError{}{conversion~from~\l_uconv_tmpf_tl ~to~\l_uconv_unit_si_tl~does~not~exist}{}{}
            } 
        }
    } {
        \GenericError{}{unable~to ~fetch~variable~#1}{}{}
    }
}

\ExplSyntaxOff


\begin{document}

\storeval{boatlength}{5}{ft}
\storeval{boatspeed}{3.5}{km/s}

\getval{boatspeed}\getunit{boatspeed}

\getval{boatlength}\getunit{boatlength}

\getvalSI{boatlength}\getunitSI{boatlength}

\getvalSI{boatspeed}\getunitSI{boatspeed}


\end{document}

相关内容