diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/pgfplots/sciformat.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/pgfplots/sciformat.sty | 861 |
1 files changed, 861 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty b/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty new file mode 100644 index 00000000000..493aca948d1 --- /dev/null +++ b/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty @@ -0,0 +1,861 @@ +%-------------------------------------------- +% +% Package sciformat.sty +% +% Provides support for floating point number representations of the +% form +% +% S * M * 10^e +% +% with S in [-,+,0], 0<M<10, e in Z. +% +% Example: +% +% +1.62452*10^-8 +% +% The conversion routines are complete text-based. +% +% Copyright 2007/2008 by Christian Feuersänger. +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see <http://www.gnu.org/licenses/>. +% +%-------------------------------------------- +\ProvidesPackage{sciformat}[2008/02/17 v.0.9.4] +\RequirePackage{pgf}[2007/01/01] +\RequirePackage{pgfplotshelpers}[2008/02/17] + +% Computes a normalised floating point representation for #1 of the +% form +% [+-]X.XXXXXXX*10^C +% where +% X.XXXXXX is a mantisse with first number != 0 +% and C is a count. +% +% This method does NOT use TeX Registers to represent the numbers! The +% computation is COMPLETELY STRING BASED. +% This allows numbers such at 10000000 or 5.23e-10 to be represented +% properly, although TeX-registers would produce overflow/underflow +% errors in these cases. +% +% It is to be used to compute logs, because log(X*10^Y) = log(X) + log(10)*Y +% +% Arguments: +% #1 a -possibly non-normalized- number representation. Accepted input +% format is +% [+-]XXXXX.XXXXXX +% [+-]XXXXX.XXXXXXeXXXX +% [+-]0.0000XXXXXX +% [+-]0.0000XXXXXXeXXXX +% NOT accepted input format is +% [+-]0000.XXXXXX [leading zeros not supported] +% [+-]XXXXX.XXXXXXEXXXXX [E notation not yet implemented] +% #2 a macro name. \def#2{.....} will be used to assign the mantisse. +% #3 a macro name. \def#3{.....} will be used to assign the exponent (base 10). +% +% Example: +% \def\normalize#1{% +% \sciparse#1\to\M\powten\E +% \[ #1 \mapsto \M\cdot 10^{\E} \] +% } +% \normalize{123.41251}% +% \normalize{3.26101452e-06}% +% +% REMARKS: +% - the mantisse will ALWAYS have a period and one following number. +% - Special case: the number +- 0 will always have the mantisse 0.0. The sign and +% the exponent is undefined. +\def\sciparse#1\to#2\powten#3{% + \begingroup + \sciparse@impl@possibly@signed#1\to#2\powten{#3}% + \xdef\sciparseTMP{% + \noexpand\def\noexpand#2{#2}% + \noexpand\def\noexpand#3{#3}% + }% + \endgroup + \sciparseTMP +} + +% Overloaded scientific parser. +% +% In addition to '\sciparse', this method checks for '+- 0' cases +% and sets #2 accordingly. +% +% \S #2: will be \def'ed to one of [0,1,2] with +% 0 == '0', ( \def#2{0} ) +% 1 == '+', +% 2 == '-', +% -> can be used with \ifcase +% \M #3: will be filled with a positive mantisse (undefined in case \S=0). +% \E #4: the exponent basis 10 (an integer). Undefined in case \S = 0. +% +% Example: +% \sciparsesign141.212\S\M\E +% -> \S = 1, \M = 1.41212, \E =2 +% +\def\sciparsesign#1#2#3#4{% + \begingroup + \sciparsesign@impl@possibly@signed#1\S#2\M#3\E{#4}% + \def\sciparseTMP{0}% + \ifx\sciparseTMP#2\relax + \def#4{0}% + \fi + \xdef\sciparseTMP{% + \noexpand\def\noexpand#2{#2}% + \noexpand\def\noexpand#3{#3}% + \noexpand\def\noexpand#4{#4}% + }% + \endgroup + \sciparseTMP +} + +\def\sciparsesignsingle#1#2{% + \begingroup + \sciparsesign{#1}\sci@S\sci@M\sci@E + \xdef\sciparseTMP{\noexpand\scisetcomponents{\noexpand#2}{\sci@S}{\sci@M}{\sci@E}}% + \endgroup + \sciparseTMP +} + +% Compares +% x = Sign(#1) #2 * 10^#3 +% with +% y = Sign(#4) #5 * 10^#6 +% +% example: +% \scimathlessthan\S\M\E\and\SS\MM\EE +% \ifscimathlessthan +% is smaller! +% \else +% is not smaller. +% \fi +% +% and sets the boolean +% \ifscimathlessthan := (x<y). +\def\scimathlessthan#1#2#3\and#4#5#6{% + \scimathlessthanfalse + \begingroup + \let\S@first=\c@pgf@counta + \let\S@second=\c@pgf@countb + \S@first\expandafter=#1\relax + \S@second\expandafter=#4\relax + \ifcase\S@first + % x = 0 -> (x<y <=> y >0) + \ifnum1=\S@second + \aftergroup\scimathlessthantrue + \fi + \or + % x > 0 -> (x<y <=> ( y > 0 && |x| < |y|) ) + \ifnum1=\S@second + % y>0: + \scimathlessthan@positive\M#2\E#3\MM#5\EE{#6}% + \fi + \or + % x < 0 -> (x<y <=> (y >= 0 || |x| > |y|) ) + \ifnum2=\S@second + % 'y<0': + \scimathlessthan@positive\M#5\E#6\MM#2\EE{#3}% + \else + \aftergroup\scimathlessthantrue + \fi + \fi + \endgroup +} + +\def\scimathmax#1#2#3\and#4#5#6\to#7#8#9{% + \scimathlessthan#1#2#3\and#4#5#6\relax + \ifscimathlessthan + \let#7=#4 + \let#8=#5 + \let#9=#6 + \else + \let#7=#1 + \let#8=#2 + \let#9=#3 + \fi +} + +\def\scimathmin#1#2#3\and#4#5#6\to#7#8#9{% + \scimathlessthan#1#2#3\and#4#5#6\relax + \ifscimathlessthan + \let#7=#1 + \let#8=#2 + \let#9=#3 + \else + \let#7=#4 + \let#8=#5 + \let#9=#6 + \fi +} + +% Takes \S, \M and \E as sign, mantisse and exponent and computes a +% fixed point representation for that number. +% +% example: +% \S=1 +% \M=4.2 +% \E=1 +% \scitofixed\S\M\E\result +% -> 42.0 +\def\scitofixed#1#2#3#4{% + \begingroup + \let\sci@sign=\c@pgf@counta + \sci@sign\expandafter=#1\relax + \ifnum0=\sci@sign + \xdef\sciparseTMP{0.0}% + \else + \expandafter\scitofixed@impl#2\E#3\END + \ifnum2=\sci@sign + \xdef\sciparseTMP{-\sciparseTMP}% + \fi + \fi + \endgroup + \let#4=\sciparseTMP +} + +% Single macro SCI-representation to #2. +\def\scitofixedsingle#1#2{% + \begingroup + \scigetcomponents{#1}\sci@S\sci@M\sci@E + \scitofixed\sci@S\sci@M\sci@E{#2}% + \global\let\sciparseTMP=#2% + \endgroup + \let#2=\sciparseTMP +} + +% Takes a SINGLE macro representing a floating point and extracts +% sign, mantisse and exponent. +% #1: the name of the single macro. +% The expansion of #1 is COMPLETELY independend of associated +% floating point number. You can even use \def#1{foo bar} +% so change the meaning of #1 without affecting the number. +% #2: will be set to #1's sign +% #3: will be set to #1's mantisse +% #4: will be set to #1's exponent +% +% @see scisetcomponents +\def\scigetcomponents#1#2#3#4{% + \expandafter\let\expandafter#2\csname\string#1@S\endcsname + \expandafter\let\expandafter#3\csname\string#1@M\endcsname + \expandafter\let\expandafter#4\csname\string#1@E\endcsname +} + +% Assigns sign #2, mantisse #3 and exponent #4 to a single macro +% representing the floating point. +% +% #1: the target name. Will create macros #1@S, #1@M and #1@E +% which will be filled with #2, #3 and #4. +% +% Remark: +% It is perfectly save to use the macro name #1 for other uses since +% only the '@{S,M,E}' - macros are used to maintain the numerical +% information. +% +% @see scigetcomponents +\def\scisetcomponents#1#2#3#4{% + \expandafter\edef\csname\string#1@S\endcsname{#2}% + \expandafter\edef\csname\string#1@M\endcsname{#3}% + \expandafter\edef\csname\string#1@E\endcsname{#4}% +} + +% Divides or multiplies the input number by 10^#4 using an arithmetic +% left/right shift. +% +% Input: +% #1 Sign macro +% #2 Mantisse macro +% #3 exponent macro +% #4 a positive or negative integer number denoting the shift. +% +% Example: +% \scimathshift\S\M\E4 +\def\scimathshift#1#2#3#4{% + \begingroup + \c@pgf@counta\expandafter=#3\relax + \advance\c@pgf@counta by#4\relax + \xdef\sciparseTMP{\the\c@pgf@counta}% + \endgroup + \let#3=\sciparseTMP +} + +\def\scimathshiftsingle#1#2{% + \begingroup + \expandafter\let\expandafter\E\csname\string#1@E\endcsname + \c@pgf@counta\expandafter=\E\relax + \advance\c@pgf@counta by#2\relax + \xdef\sciparseTMP{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname\string#1@E\endcsname\sciparseTMP% +} + + +% Rounds a fixed point number #1 to #2 digits precision and returns +% the result into macro #3. +% +% This method is PURELY text based and can work with arbirtrary +% precision (well, limited to TeX's stack size and integer size). +\def\fixedpointround#1\prec#2\to#3{% + \begingroup + \pgfplots@toka={}% + \let\fp@round@next=\empty + \let\fp@round@prec=\c@pgf@countb + \let\fp@offsetbehindperiod=\c@pgf@counta + \let\fp@round@lastzeros=\c@pgf@countc + \let\fp@round@trg=#3\relax + \def\fp@round@input{#1}% + \fp@round@prec=#2\relax + \fp@round@lastzeros=0 + \fp@offsetbehindperiod=-1 % means: no period found so far + \fixedpointround@impl@ITERATE@NODOT #1\fp@round@EOI + \xdef\sciparseTMP{\fp@round@trg}% + \endgroup + \let#3=\sciparseTMP +} + + + +%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% IMPL +% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \fixedpointround implementation in WORDS: +% +% coarse idea: +% 1. collect all digits/sign BEFORE the first period in REVERSE order +% 2. then, collect UP TO \prec digits after the period in REVERSE order +% Steps 1. and 2. lead to the digit [sign] sequence +% "x_{-p} x_{-p+1} ... x_{-2} x_{-1} '.' x_0 ... x_r" +% where 'r' is the total number of digits. The integer 'p' denotes the +% ACTUALLY collected number of digits behind the period. +% +% Let 'k' be the desired precision. +% +% There are exactly TWO cases: +% 1. The case with p<=k and x_{-p-1} = end of input. +% 2. The case with p=k and x_{-p-1} is a further, next character. +% +% Then, we do in case 1.) +% discard any unused zeros at the tail of our number (possibly +% including the period) +% +% and in case 2.) +% if NEXT DIGIT < 5: +% do exactly the same as in case 1.) above and discard any +% following digits. +% else +% let q := -p +% while(x_q = 9 and q<=r ) +% if q>=0 +% set x_q = '0' +% else +% discard digit x_q='9' +% fi +% ++q +% if q=0 +% discard the period +% fi +% end while +% if q = r+1 +% insert a '1' +% else +% set x_q = x_q + 1 +% fi +% fi +% +% All these loops have been implemented in spaghetti-code below. +% Sorry, I fear its hard to understand. In principle, everything is +% realised using more or less finite state machines (with some number +% counting logic). +% +% Some comments: +% - The token register \pgfplots@toka is used to accumulate the REVERSED input number. +% - \fp@round@EOI always denotes 'END OF INPUT'. +% - in the second stage, we need to reverse \pgfplots@toka. +% This is -again- done with \pgfplots@toka. + +\def\fixedpointround@impl@discard@period#1.#2\fp@round@EOI{% + \def\fp@round@trg{#1}% +} + +\def\fixedpointround@impl@gobble@rest@and@start#1\fp@round@EOI{% + \fixedpointround@impl@start +} +\def\fixedpointround@impl@gobble@and@start\fp@round@EOI{% + \fixedpointround@impl@start +} +\def\fixedpointround@impl@gobble\fp@round@EOI{}% + +\def\fixedpointround@impl@start{% + \ifx\fp@round@next\empty + \ifnum\fp@offsetbehindperiod<0 + \edef\fp@round@trg{\fp@round@input}% + \else + \ifnum\fp@offsetbehindperiod>\fp@round@prec + \errmessage{Internal logic error in fixedpointround at [I] - should not have happened!?}% + \fi + \fixedpointround@impl@discard@suffix@zeros + \fi + \else + \ifnum\fp@offsetbehindperiod=\fp@round@prec + \else + \errmessage{Internal logic error in fixedpointround at [II] - should not have happened!? I have offsetbehindperiod=\the\fp@offsetbehindperiod and prec = \the\fp@round@prec}% + \fi + \expandafter\ifnum\fp@round@next<5 + \fixedpointround@impl@discard@suffix@zeros + \else + \multiply\fp@offsetbehindperiod by-1 + %\edef\fp@round@trg{B\the\pgfplots@toka B}% + \expandafter\fixedpointround@impl@ADD@ONE\the\pgfplots@toka\fp@round@EOI + \fi + \fi +} + +\def\fixedpointround@impl@ADD@ONE{% + \pgfplots@toka={}% + \fixedpointround@impl@ADD@ONE@ITERATE +} +\def\fixedpointround@impl@ADD@ONE@ITERATE{% + \@ifnextchar\fp@round@EOI{% + \edef\fp@round@trg{1\the\pgfplots@toka}% + \fixedpointround@impl@gobble + }{% + \@ifnextchar.{% + \fixedpointround@impl@ADD@ONE@NEXT@COLLECT + }{% + \@ifnextchar+{% + \fixedpointround@impl@ADD@ONE@NEXT@COLLECT + }{% + \@ifnextchar-{% + \fixedpointround@impl@ADD@ONE@NEXT@COLLECT + }{% + \fixedpointround@impl@ADD@ONE@NEXT + }% + }% + }% + }% +} + +\def\fixedpointround@impl@ADD@ONE@ITERATE@gobble@dot.{% + \fixedpointround@impl@ADD@ONE@ITERATE +} + +\def\fixedpointround@impl@ADD@ONE@NEXT@COLLECT#1{% + \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}% + \fixedpointround@impl@ADD@ONE@ITERATE +} +\def\fixedpointround@impl@ADD@ONE@NEXT#1{% + \ifnum#1=9 + \ifnum\fp@offsetbehindperiod<0 + % silently DROP digit + \else + \pgfplots@toka=\expandafter{\expandafter0\the\pgfplots@toka}% + \fi + \advance\fp@offsetbehindperiod by1 + \ifnum\fp@offsetbehindperiod=0 + \def\fp@round@nextcmd{\fixedpointround@impl@ADD@ONE@ITERATE@gobble@dot}% + \else + \def\fp@round@nextcmd{\fixedpointround@impl@ADD@ONE@ITERATE}% + \fi + \else + % re-use this counter: + \fp@round@lastzeros=#1 + \advance\fp@round@lastzeros by1 + \edef\fp@round@trg{\the\fp@round@lastzeros\the\pgfplots@toka}% + \pgfplots@toka=\expandafter{\fp@round@trg}% + \def\fp@round@nextcmd{\fixedpointround@impl@REVERSE@ITERATE}% + \fi + \fp@round@nextcmd +} + + +\def\fixedpointround@impl@discard@suffix@zeros{% + \ifnum\fp@round@lastzeros=\fp@offsetbehindperiod + \expandafter\fixedpointround@impl@discard@period\fp@round@input\fp@round@EOI + \else + \ifnum\fp@round@lastzeros=0 + \expandafter\fixedpointround@impl@REVERSE\the\pgfplots@toka\fp@round@EOI + \else + \expandafter\fixedpointround@impl@discard@suffix@zeros@ITERATE\the\pgfplots@toka\fp@round@EOI + \fi + \fi +} + +% PRECONDITION: +% \fp@round@lastzeros > 0 +\def\fixedpointround@impl@discard@suffix@zeros@ITERATE#1{% + \advance\fp@round@lastzeros by-1 + \ifnum\fp@round@lastzeros=0 + \def\fp@round@nextcmd{\fixedpointround@impl@REVERSE}% + \else + \def\fp@round@nextcmd{\fixedpointround@impl@discard@suffix@zeros@ITERATE}% + \fi + \fp@round@nextcmd +} + +\def\fixedpointround@impl@REVERSE{% + \pgfplots@toka={}% + \fixedpointround@impl@REVERSE@ITERATE +} + +\def\fixedpointround@impl@REVERSE@ITERATE{% + \@ifnextchar\fp@round@EOI{% + \edef\fp@round@trg{\the\pgfplots@toka}% + \fixedpointround@impl@gobble + }{% + \fixedpointround@impl@REVERSE@NEXT + }% +} + +\def\fixedpointround@impl@REVERSE@NEXT#1{% + \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}% + \fixedpointround@impl@REVERSE@ITERATE +} + +\def\fixedpointround@impl@BEGIN@DOT.{% + \pgfplots@toka=\expandafter{\expandafter.\the\pgfplots@toka}% + \fp@offsetbehindperiod=0 + \fixedpointround@impl@ITERATE@DOT +} +\def\fixedpointround@impl@ITERATE@DOT{% + \@ifnextchar\fp@round@EOI{% + % finished. + \fixedpointround@impl@gobble@and@start + }{% + \fixedpointround@impl@NEXT@DOT + }% +} +\def\fixedpointround@impl@NEXT@DOT#1{% + \ifnum\fp@offsetbehindperiod=\fp@round@prec + \def\fp@round@next{#1}% + \def\fp@round@nextcmd{\fixedpointround@impl@gobble@rest@and@start}% + \else + \advance\fp@offsetbehindperiod by1 + \ifnum#1=0 + \advance\fp@round@lastzeros by1 + \else + \fp@round@lastzeros=0 + \fi + \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}% + \def\fp@round@nextcmd{\fixedpointround@impl@ITERATE@DOT}% + \fi + \fp@round@nextcmd +}% + +\def\fixedpointround@impl@ITERATE@NODOT{% + \@ifnextchar\fp@round@EOI{% + \fixedpointround@impl@gobble@and@start + }{% + \@ifnextchar.{% + \fixedpointround@impl@BEGIN@DOT + }{% + \fixedpointround@impl@NEXT@NODOT + }% + }% +} +\def\fixedpointround@impl@NEXT@NODOT#1{% + \pgfplots@toka=\expandafter{\expandafter#1\the\pgfplots@toka}% + \fixedpointround@impl@ITERATE@NODOT +}% + +%-------------------------------------------- +% END of fixedpointround implementation. +%-------------------------------------------- + +\newif\ifscimathlessthan + +% first character MAY be + or -. This is checked, then +% \sciparse@impl@positive will be called for the +% absolute value. The sign is inserted afterwards. +\def\sciparse@impl@possibly@signed#1#2\to#3\powten#4{% + \def\sciparseTMP{#1}% + \def\sciparseTMPB{-}% + \if\sciparseTMP\sciparseTMPB + \sciparse@impl@positive@possibly@noperiod#2.\to#3\powten#4\S\sciparseTMPB% + \edef#3{-#3}% + \else + \def\sciparseTMPB{+}% + \if\sciparseTMP\sciparseTMPB + \sciparse@impl@positive@possibly@noperiod#2.\to#3\powten#4\S\sciparseTMPB% + \else + \sciparse@impl@positive@possibly@noperiod#1#2.\to#3\powten#4\S\sciparseTMPB% + \fi + \fi +} + +% the same as above, only the return value is different. +\def\sciparsesign@impl@possibly@signed#1#2\S#3\M#4\E#5{% + \def\sciparseTMP{#1}% + \def\sciparseTMPB{-}% + \if\sciparseTMP\sciparseTMPB + \def#3{2}% + \sciparse@impl@positive@possibly@noperiod#2.\to#4\powten#5\S#3% + \else + \def#3{1}% + \def\sciparseTMPB{+}% + \if\sciparseTMP\sciparseTMPB + \sciparse@impl@positive@possibly@noperiod#2.\to#4\powten#5\S#3% + \else + \sciparse@impl@positive@possibly@noperiod#1#2.\to#4\powten#5\S#3% + \fi + \fi +} + +% XXXX -> XXXX.0 +% XXXX.YYY -> XXXX.YYYY +\def\sciparse@impl@positive@possibly@noperiod#1.#2\to#3\powten#4\S#5{% +%\tracingmacros=2\tracingcommands=2 + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + \sciparse@impl@positive@noperiod@possibly@SCI#1e\to#3\powten#4\S{#5}% + \else + \expandafter\sciparse@impl@positive\sciformat@pop@last@of@two@dots#1.#2\to#3\powten#4\S{#5}% + \fi +} +\def\sciformat@pop@last@of@two@dots#1.#2.{#1.#2}% + +\def\sciparse@impl@positive@noperiod@possibly@SCI#1e#2\to#3\powten#4\S#5{% + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + % this case applies to + % 1234 -> 1234.0 + \sciparse@impl@positive#1.0\to#3\powten#4\S{#5}% + \else + % this case applies to + % 1e1 -> 1.0e1 + % in this case, #1e#2 = 1e1e, so we have to discard a suffix 'e'. + \edef\sciparseTMP{#1.0e\sciformat@popsuffix@e@expansion#2}% + \expandafter\sciparse@impl@positive\sciparseTMP\to#3\powten#4\S{#5}% + \fi +} + +% XXXXX.XXXXX -> X.XXXXXXX * 10^4 +% 0.0000XXXXX -> X.XXXX * 10^{-5} +% +% or +% XXXX.XXXXXeYYY -> X.XXXXXX* 10^{3+YYY} +% 0.0000XXXXeYYY -> X.XXX* 10^{-5+YYY} +% +% this version does not accept a sign. A period is required. +% +% The return value #6 will be \def'ed to '0' if the resulting mantisse is '0'. +% Won't be touched otherwise. +\def\sciparse@impl@positive#1#2.#3\to#4\powten#5\S#6{% +% \begingroup +% FIXME! restore variables!! +%\tracingmacros=2\tracingcommands=2 +%\tracingmacros=0\tracingcommands=0 + \sciparse@positive@getexisting@exponent@e#3e\preexponentto\preexponentstring\exponenttocount\c@pgf@counta + % will \c@pgf@counta will be initialised in the line above + % \c@pgf@counta=0 + \ifnum#1=0 + % the case 0.0000XXXX + % does also handle 0.0000XXXXeXXX + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + \c@pgf@countb=0 + \expandafter\sciformat@count@leading@zeros\preexponentstring\to\c@pgf@countb + \advance\c@pgf@countb by1 + \advance\c@pgf@counta by-\c@pgf@countb + \edef#5{\the\c@pgf@counta}% + \expandafter\sciformat@assignmantisse\preexponentstring\to#4\countdownzerosfrom\c@pgf@countb\S{#6}% + \else + % the case 000.0000XXXXX + % is not allowed and does not make sense. + \errmessage{INVALID NUMBER FORMAT: leading zeros 00*.* not supported yet}% + \fi + \else + % the case NXXXXX.XXXXXXX + % or NXXXXXX.XXXXXXeXXXX + % where N in [1-9] + \sciformat@strlen#1#2\to\c@pgf@counta + \advance\c@pgf@counta by-1 + \edef#4{#1.#2\preexponentstring}% + \edef#5{\the\c@pgf@counta}% + \fi +%\tracingmacros=0\tracingcommands=0 +% \endgroup +} + +% parses scientific notation and returns the exponent and everything +% before the exponent like +% +% XXXXXXXeYYYY -> \def#2{XXXXXXX} #3=YYYY +% or +% XXXXXXXXe -> \def#2{XXXXXXXX} #3=0 +% +% Examples: +% - \sciparse@exponent@e123456e\preexponentto\M\exponenttocount\acount +% \M->123456 +% \acount=0 +% Please note that the input was 123456e -> at least 'e' is expected! +% +% - \sciparse@exponent@e123456e-10e\preexponentto\M\exponenttocount\acount +% \M->123456 +% \acount=-10 +% Again, the suffix 'e' is REQUIRED. This allows to reduce \ifs. +\def\sciparse@positive@getexisting@exponent@e#1e#2\preexponentto#3\exponenttocount#4{% + \def#3{#1}% + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + #4=0 + \else + \sciformat@popsuffix@e#2\tocount{#4}% + \fi +} + +% XXXXXe -> #2=XXXXX where X in [+-0-9]. +\def\sciformat@popsuffix@e#1e\tocount#2{% + #2=#1 +} + +\def\sciformat@popsuffix@e@expansion#1e{% + #1% +}% + +% 00000XXXXXX -> X.XXXXX +% Inputs: +% #1 = 00000XXXXXX +% #2 a macro name +% #3 a count in which the number of zeros plus one is contained (i.e. +% the number of shifts). +% #4 a macro name which will be \def'ed to '0' if the resulting +% mantisse is 0. Won't be touched otherwise. +\def\sciformat@assignmantisse#1\to#2\countdownzerosfrom#3\S#4{% + \pgfplots@toka={#1}% + \loop + \ifnum#3=1 + \else + \expandafter\sciformat@popfirst\the\pgfplots@toka\to{\pgfplots@toka}% + \advance#3 by-1 + \repeat + \edef\sciformat@assignmantisseTMP{\the\pgfplots@toka}% + \ifx\sciformat@assignmantisseTMP\empty + % The case 0.0 * 10^0 + \def#2{0.0}% + \def#4{0}% + \else + \expandafter\sciformat@insertperiod\the\pgfplots@toka\to{#2}% + \fi +} + +% XXXXXX -> X.XXXXX into #3 +\def\sciformat@insertperiod#1#2\to#3{% + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + \def#3{#1.0}% + \else + \def#3{#1.#2}% + \fi +} + +% discards the first token. +\def\sciformat@popfirst#1#2\to#3{% + #3={#2}% +} + +% adds the string length of #1#2 into the count register #3. +% +% The register won't be initialised to zero! +\def\sciformat@strlen#1#2\to#3{% + \advance#3 by1 + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + \else + \sciformat@strlen#2\to{#3}% + \fi +} + +% Adds the number of leadings zeros of #1#2 into the count register +% #3. +% +% The register won't be initialised to zero! +\def\sciformat@count@leading@zeros#1#2\to#3{% + \ifnum#1=0 + \advance#3 by1 + \def\sciparseTMP{#2}% + \ifx\sciparseTMP\empty + \else + \sciformat@count@leading@zeros#2\to{#3}% + \fi + \fi +} + + + + + + +\def\scimathlessthan@positive\M#1\E#2\MM#3\EE#4{% + \c@pgf@counta\expandafter=#2\relax + \c@pgf@countb\expandafter=#4\relax + \ifnum\c@pgf@counta<\c@pgf@countb + \aftergroup\scimathlessthantrue + \else + \ifnum\c@pgf@counta=\c@pgf@countb\relax + \pgfmath@xa\expandafter=#1 pt\relax + \pgfmath@xb\expandafter=#3 pt\relax + \ifdim\pgfmath@xa<\pgfmath@xb + \aftergroup\scimathlessthantrue + \fi + \fi + \fi +} + +\def\scitofixed@impl#1.#2\E#3\END{% + \let\scitofixed@exponent=\c@pgf@countb + \scitofixed@exponent\expandafter=#3\relax + \ifnum\scitofixed@exponent<0 + \pgfplots@toka={0.}% + \loop + \ifnum\scitofixed@exponent<-1 + \pgfplots@toka=\expandafter{\the\pgfplots@toka 0}% + \advance\scitofixed@exponent by1 + \repeat + \def\sciparseTMPB{#2}% + \def\sciparseTMPC{0}% + \ifx\sciparseTMPB\sciparseTMPC + \xdef\sciparseTMP{\the\pgfplots@toka #1}% + \else + \xdef\sciparseTMP{\the\pgfplots@toka #1#2}% + \fi + \else + \ifnum\scitofixed@exponent=0 + \xdef\sciparseTMP{#1.#2}% + \else + \pgfplots@toka={#1}% + \scitofixed@impl@collectmantisse#2\count\scitofixed@exponent + \xdef\sciparseTMP{\the\pgfplots@toka}% + \fi + \fi +} + +\def\scitofixed@impl@collectmantisse#1#2\count#3{% + \pgfplots@toka=\expandafter{\the\pgfplots@toka #1}% + \advance\scitofixed@exponent by-1 + \def\sciparseTMPB{#2}% + \ifx\sciparseTMPB\empty + \loop + \ifnum\scitofixed@exponent>0 + \pgfplots@toka=\expandafter{\the\pgfplots@toka 0}% + \advance\scitofixed@exponent by-1 + \repeat + \else + \ifnum\scitofixed@exponent=0 + \pgfplots@toka=\expandafter{\the\pgfplots@toka .#2}% + \else + \scitofixed@impl@collectmantisse#2\count#3% + \fi + \fi +} |