summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/pgfplots/sciformat.sty
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/pgfplots/sciformat.sty')
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/sciformat.sty861
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
+}