因此,我必须使用英制和公制单位进行大量计算。我正在寻找一种以 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}