正しいSI単位プレフィックスを使用するように数値を自動的に変換します
Automatically Convert Number Use Correct Si Unit Prefix
解決:
両方の入力フォームを解決するために編集されました。科学的記数法で大文字または小文字のEが許可されるように編集されました(例:1E6または
1e6)。
標準単位で1、10、または100の乗数を自動的に識別するように編集されています。
プレフィックスが1E-24から1E26の範囲外の場合、??が出力されます。
見る 補足 乗数のより一般的な使用(1、10、100以外)。
この答えはEDITSで拡張されたので、ロジックを説明しましょう。互いに順番に呼び出す3つのマクロがあります。最後から最初まで頑張っていきましょう。最下位レベルのマクロは
prefixSN [] {1E}乗数のデフォルトは1ですが、10または100にすることができます。SIプレフィックス整数は、SIプレフィックスが定義されている特定の整数です(-24、-21、...- 6、-3、-2、-1)。 、0、1、2、3、6、... 21、24)。指定された整数がこのリストにない場合、??が出力されます。整数がリストにある場合、乗数の後に適切なSIプレフィックスが出力されます。
フィードするマクロ適切な構文の prefixSNが呼び出されます prefixmult、構文付き
prefixmult {1E}ここで、整数は-24〜26の範囲にある必要があります。整数の値に基づいて、プレフィックスを1、10、または100に設定し、整数を次に低いSI標準値に調整します。たとえば、 prefixmultは1E5、それは呼び出しを設定します prefixSI [100] {1E3}。
トップレベルのマクロ、フィードする prefix prefixmultその整数形式で、4つの可能な形式で入力を受け取ることができます。
prefix {1E} prefix {1e} prefix {100} prefix {.001}それは探して分類しますEまたはe。 1つを見つけると、大文字のEフォームがに渡されます。 prefixmultと関連する整数。いいえの場合Eが見つかり、小数点を探します。1以上0トークン。見つかったものに基づいて、ゼロの数に基づいて関連する整数を再構築し、それをに渡します prefixmult。
これがMWEです。
documentclass {article} usepackage {siunitx、listofitems} newcommand prefixSN [2] [1] {#1 、 prefixSNaux#2 Relax} def prefixSNaux 1E#1 Relax {% ifnum#1 = 0 relax else ifnum#1 = -1 relax textrm {d} else ifnum#1 = -2 relax textrm {c} else ifnum#1 = -3 relax textrm {m } else ifnum#1 = -6 relax textrm { ensuremath { mu}} else ifnum#1 = -9 Relax textrm {n} else ifnum#1 = -12 Relax textrm {p} else ifnum#1 = -15 Relax textrm {f} else ifnum#1 = -18 relax textrm {a} else ifnum#1 = -21 Relax textrm { z} else ifnum#1 = -24 relax textrm {y} else ifnum#1 = 1 relax textrm {da} else ifnum#1 = 2 relax textrm {h} else ifnum#1 = 3 relax textrm {k} else ifnum#1 = 6 relax textrm {M} else ifnum#1 = 9 relax textrm {G} else ifnum#1 = 12 relax textrm {T} else ifnum#1 = 15 relax textrm {P} else ifnum#1 = 18 relax textrm {E} else ifnum#1 = 21 relax textrm {Z} else ifnum#1 = 24 Relax textrm {Y} else ??% fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi} newcommand prefix [1] {% setsepchar1e% readlist scinot {#1}% ifnum scinotlen> 1 Relax itemt omacro scinot [2] temp% expandafter prefixmult expandafter { expandafter1 expandafter E temp}% else setsepchar {./1/0}% readlist zerocount {#1}% ifnum zerocountlen = 1 Relax expandafter prefixmult expandafter { expandafter1 expandafter E% the numexpr listlen zerocount [1,2] -1 Relax}% else expandafter prefixmult expandafter { expandafter1 expandafter E % expandafter- the numexpr listlen zerocount [2,1] Relax}% fi fi} newcommand prefixmult [1] { prefixmultaux#1 Relax} def prefixmultaux 1E#1 Relax {% setsepcharE25% readlist factormult {E#1}% ifnum factormultlen> 1 Relax prefixSN [10] {1E the numexpr#1-1 Relax} else setsepchar% readlist factormult {E#1}% ifnum factormultlen> 1 Relax prefixSN [100] {1E the numexpr#1-2 Relax} else prefixSN [1] {1E#1}% fi fi} begin {document} prefix {1E6} par prefix {1E-15} par prefix {1e-6} par prefix {100} par prefix {1000000} par prefix {.001} par prefix {.000001} par prefix {1E5} par prefix {10000} par prefix {.0001} par prefix {1E7} par prefix {1E-5 } par prefix {1E8} par prefix {1E-4} end {document}
補足
これが改善であるかどうかはわかりません。 prefixは、10の累乗のみで処理する必要があります。ただし、任意の乗数を処理できる、より一般的な実装が必要な場合 有効数字1桁の 、そしてここにあります:
documentclass {article} usepackage {siunitx、listofitems} newcommand prefixSN [2] [1] {#1 、 prefixSNaux#2 Relax} def prefixSNaux 1E#1 Relax {% ifnum#1 = 0 relax else ifnum#1 = -1 relax textrm {d} else ifnum#1 = -2 relax textrm {c} else ifnum#1 = -3 relax textrm {m } else ifnum#1 = -6 relax textrm { ensuremath { mu}} else ifnum#1 = -9 Relax textrm {n} else ifnum#1 = -12 Relax textrm {p} else ifnum#1 = -15 Relax textrm {f} else ifnum#1 = -18 relax textrm {a} else ifnum#1 = -21 Relax textrm { z} else ifnum#1 = -24 relax textrm {y} else ifnum#1 = 1 relax textrm {da} else ifnum#1 = 2 relax textrm {h} else ifnum#1 = 3 relax textrm {k} else ifnum#1 = 6 relax textrm {M} else ifnum#1 = 9 relax textrm {G} else ifnum#1 = 12 relax textrm {T} else ifnum#1 = 15 relax textrm {P} else ifnum#1 = 18 relax textrm {E} else ifnum#1 = 21 relax textrm {Z} else ifnum#1 = 24 Relax textrm {Y} else ??% fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi} newcommand prefix [1] {% setsepchare% readlist scinot {#1}% ifnum scinotlen> 1 Relax itemto macro scinot [1] premult% itemtomacro scinot [2] temp% expandafter expandafter expandafter prefixmult expandafter expandafter expandafter {% expandafter premult expandafter E temp}% else setsepchar8 % readlist zerocount {#1}% ifnum zerocountlen = 1 Relax expandafter expandafter expandafter def expandafter expandafter expandafter temp expandafter expandafter expandafter { zerocountsep [1,1]}% expandafter expandafter expandafter prefixmult expandafter expandafter expandafter {% expandafter temp expandafter E% the numexpr listlen zerocount [1,2] -1 Relax}% else expandafter expandafter expandafter def expandafter expandafter expandafter temp expandafter expandafter expandafter { zerocountsep [2,1]}% expandafter expandafter expandafter prefixmult expandafter expandafter expandafter {% expandafter temp expandafter E % expandafter- the numexpr listlen zerocount [2,1] Relax}% fi fi} newcommand prefixmult [1] { prefixmultaux#1 Relax} def prefixmultaux#1E#2 リラックス{% setsepchar% readli st factormult {E#2}% ifnum factormultlen> 1 Relax prefixSN [#10] {1E the numexpr#2-1 Relax} else setsepchar% readlist factormult {E#2} % ifnum factormultlen> 1 Relax prefixSN [#100] {1E the numexpr#2-2 relax} else prefixSN [#1] {1E#2}% fi fi} begin { document} prefix {4E6} par prefix {1E-15} par prefix {1e-6} par prefix {300} par prefix {1000000} par prefix {.001} par prefix {.000004} par prefix {1E5} par prefix {10000} par prefix {.0001} par prefix {5E7} par prefix {1E-5} par prefix {3E8} par prefix {1E-4} end {document}
これは、指数表記と標準表記の両方をサポートします。
ゼロ以外の数字に関するチェックは実行されず、入力は次の形式であると見なされます。
1 -1 1e 1E -1e -1E範囲は-1E-26から1E26。この範囲外の数値は黙って失敗します。範囲に関する制御を追加できます。
コードは次のとおりです。作業の大部分はによって実行されることに注意してください __ nebuch_prefix_exp:nn(正確には:eeバリアント)。
documentclass {article} usepackage {siunitx}%はxparseとexpl3もロードします ExplSyntaxOn NewDocumentCommand { prefix} {m} { nebuch_prefix:e { tl_lower_case:n {#1}}} seq_new:N l__nebuch_prefix_input_seq cs_new_protected:Nn nebuch_prefix:n { seq_set_split:Nnn l__nebuch_prefix_input_seq {e} {#1} int_compare:nTF { seq_count:N l__nebuch_prefix_input_seq> 1} {%e / EがあったNn l__nebuch_prefix_input_seq {1}} { seq_item:Nn l__nebuch_prefix_input_seq {2}}} {%no e / E __ nebuch_prefix_long:n {#1}}} cs_generate_variant:Nn neb_ __ nebuch_prefix_exp:nn { int_compare:nTF { int_mod:nn {#2} {3}<0 } { \__nebuch_prefix_exp:ee { #1 prg_replicate:nn { 3 + int_mod:nn { #2 } { 3 } } { 0 } } { int_eval:n { #2 - 3 - int_mod:nn { #2 } { 3 } } } } { SI { #1 % 1 or -1 prg_replicate:nn { int_mod:nn { #2 } { 3 } } { 0 } } { int_case:nn { int_div_truncate:nn { #2 } { 3 } } { {-8}{yoctovoidunit} {-7}{zeptovoidunit} {-6}{attovoidunit} {-5}{femtovoidunit} {-4}{picovoidunit} {-3}{
anovoidunit} {-2}{microvoidunit} {-1}{millivoidunit} {0}{!voidunit} {1}{kilovoidunit} {2}{megavoidunit} {3}{gigavoidunit} {4}{ eravoidunit} {5}{petavoidunit} {6}{exavoidunit} {7}{zettavoidunit} {8}{yottavoidunit} } } } } cs_generate_variant:Nn \__nebuch_prefix_exp:nn {ee} cs_new_protected:Nn \__nebuch_prefix_long:n { % count the number of zeros
egex_split:nnN { (-*1+) } { #1 } l__nebuch_prefix_input_seq \__nebuch_prefix_exp:ee { seq_item:Nn l__nebuch_prefix_input_seq { 2 } } { l_count:e { seq_item:Nn l__nebuch_prefix_input_seq { 3 } } } } cs_generate_variant:Nn l_count:n { e } ExplSyntaxOff DeclareSIUnit{voidunit}{
elax} egin{document} prefix{1e0} prefix{1e2} prefix{1E4} prefix{-1E20} prefix{1} prefix{10} prefix{100} prefix{1000} prefix{10000} prefix{100000} prefix{1000000} prefix{10000000} prefix{100000000} prefix{1000000000} prefix{-10000000000} prefix{100000000000} prefix{1E6} prefix{1E24} prefix{-1E-6} prefix{1E-8} prefix{-1E-7} end{document}
これにより、任意の(もちろん有効な)値または式を入力できます。コード(ab)は、LaTeX3浮動小数点ユニットを使用して入力式を解析し、指数表記に変換します。これで、コードはその番号に適用する正しいプレフィックスを探すだけです。範囲外の数値は、最も近いプレフィックスに合うように、より多くの桁で出力されます( NS。、 1E28プリント10000Yおよび1E-28プリント0.0001および)。
NS prefixマクロ(おそらく呼び出されるはずです postfix
:-)は展開可能で、1つの引数、数値を取り、それに続いて接頭辞を出力します。
NS prefixSIマクロは展開可能ではなく、と同じ署名を持っていますsiunitxの SIマクロ。 prefixSIは、最初の必須引数を次のように評価します。 prefix( nebu_prefix:n、実際には)、上記のように、それをに渡します SI。選択したプレフィックスはに保存されます prefix(グループ内で、 大きい prefixはagianで使用できます)これは、たとえば、単位式で使用できます prefixSI {1000} { prefix metre}は印刷します1キロ。
プレフィックスは次のように宣言できます setprefix {} {}、like setprefix centi {c} {-2}。確認してくださいが存在します。使用しない場合 prefixSI次に、使用できますそこにリラックス。
そして、コードが使用するように数値を解析するためのexpl3の浮動小数点ユニット。aEbまたは10進表記。で実装されている任意の浮動小数点演算を実行できますl3fp(それらのリストについてはここを見てください)のようにa * 10 ^ bまたはその他。
documentclass {article} usepackage {siunitx} ExplSyntaxOn%Internals int_new:N l__nebu_min_prefix_int tl_new:N l__nebu_base_number_tl tl_new:N l__nebu_mode_tl cs_new:Npn nebu_prefix:n#1 { _ n { exp_args:Nf fp_to_scientific:n { tl_lower_case:n {#1}}}} cs_new:Npn __ nebu_prefix:n#1 { __ nebu_prefix:nwnw#1 q_stop} cs_new:Npn __ nebu_prefix:nw #1 e#2 q_stop { __ nebu_find_prefix:nnn {#2} {#1} {1}} cs_new:Npn __ nebu_find_prefix:nnn#1#2#3 { tl_if_exist:cT {l__nebu_#1 tl_use: N l__nebu_mode_tl _prefix_tl} { use_i_delimit_by_q_stop:nw { __ nebu_output:nnn {#2} {#1} {#3}}} int_compare:nNnT {#1}