Below is some shortened version of some code I wrote that can automatically format a number from decimal to scientific notation. I have been using it for some time now and have a few ideas how to combine it with some other work I have done into a small package for engineering calculations. However, looking back at what was a couple of hours of work, it definitely needs a good overhaul.
The code provides two major author commands \snotation{}
and \enotation{}
that return the input number in scientific or engineering notation.
I tend to go for readability of code rather than algorithmic elegance and find it easier to write the code than read through it later and change it. Neither loops nor if constructions are very reliable with TeX and I chose to "cut and paste code" rather than using these more error prone parts of TeX constructions.
Where can I find some information about re-factoring and polishing TeX code. Have you got a good strategy or tips and suggestions?
Here is the code as a working minimal (excludes the engineering part).
\documentclass{article}
\usepackage{fp,siunitx}
\begin{document}
\gdef\SetNumDecimals#1{\gdef\numdecimals{#1}}
\SetNumDecimals{10}
%% Helper routine for formatting numbers
%% first it round to 4 decimal numbers
%% then it clips the number so that if trailing
%% zeroes exist it removes them prints 16.01 and not 16.010000000
\newcommand\Clip[1]{\FPround\tmp{#1}{\numdecimals}\FPclip\tmp{\tmp}\tmp}%
\newcommand\Clipsmall[1]{\FPclip\tmp{#1}\tmp}%
\gdef\typeset#1#2{
\def\clippednumber{\Clip{#1}}
\def\powers##1{$##1 \times10^{#2}$}
\powers{\clippednumber}
}
\gdef\typesetsmall#1#2{
\def\clippednumber{\Clipsmall{#1}}
\def\powers##1{$##1 \times10^{#2}$}
\powers{\clippednumber}
}
\FPset\PowerOne{10}
\FPset\PowerTwo{100}
\FPset\PowerThree{1000}
\FPset\PowerFour{10000}
\FPset\PowerFive{100000}
\FPset\PowerSix{1000000}
\FPset\PowerSeven{10000000}
\FPset\PowerEight{100000000}
\FPset\PowerNine{1000000000}
\FPset\PowerTen{10000000000}
\FPset\PowerEleven{100000000000}
\FPset\PowerTwelve{1000000000000}
\FPset\PowerFifteen{1000000000000000}
\gdef\Epower{}
\gdef\result{}
\def\Powers#1{%
\FPset\Number{#1}
\FPifgt\Number\PowerTwo
\FPdiv\temp{\Number}{\PowerTwo}
\def\Epower{3}
\FPset\result\temp
\fi
\FPifgt\Number\PowerThree
\FPdiv\temp{\Number}{\PowerThree}
\def\Epower{3}
\global\let\result\temp
\fi
\FPifgt\Number\PowerFour
\FPdiv\temp{\Number}{\PowerFour}
\def\Epower{4}
\global\let\result\temp
\fi
\FPifgt\Number\PowerFive
\FPdiv\temp{\Number}{\PowerFive}
\def\Epower{5}
\global\let\result\temp
\fi
\FPifgt\Number\PowerSix
\FPdiv\temp{\Number}{\PowerSix}
\def\Epower{6}
\global\let\result\temp
\fi
\FPifgt\Number\PowerSeven
\FPdiv\temp{\Number}{\PowerSeven}
\def\Epower{7}
\global\let\result\temp
\fi
\FPifgt\Number\PowerEight
\FPdiv\temp{\Number}{\PowerEight}
\def\Epower{8}
\global\let\result\temp
\fi
\FPifgt\Number\PowerNine
\FPdiv\temp{\Number}{\PowerNine}
\def\Epower{9}
\global\let\result\temp
\fi
\FPifgt\Number\PowerTen
\FPdiv\temp{\Number}{\PowerTen}
\def\Epower{10}
\global\let\result\temp
\fi
\FPifgt\Number\PowerEleven
\FPdiv\temp{\Number}{\PowerEleven}
\def\Epower{11}
\global\let\result\temp
\fi
\FPifgt\Number\PowerTwelve
\FPdiv\temp{\Number}{\PowerTwelve}
\def\Epower{12}
\global\let\result\temp
\fi
\typeset{\result}{\Epower}
}
\FPset\one{1}
\def\piconums#1{%
\FPset\Number{#1}
\FPiflt\Number\one
\FPmul\temp{\Number}{\PowerOne}
\def\Epower{-1}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerTwo}
\def\Epower{-2}
\global\let\result\temp
\else
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerThree}
\def\Epower{-3}
\global\let\result\temp
\else
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerFour}
\def\Epower{-4}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerFive}
\def\Epower{-5}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerSix}
\def\Epower{-6}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerSeven}
\def\Epower{-7}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerEight}
\def\Epower{-8}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerNine}
\def\Epower{-9}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerTen}
\def\Epower{-10}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerEleven}
\def\Epower{-11}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerTwelve}
\def\Epower{-12}
\global\let\result\temp
\fi
\FPiflt\result\one
\FPmul\temp{\Number}{\PowerFifteen}
\def\Epower{-15}
\global\let\result\temp
\fi
\typesetsmall{\result}{\Epower}
}
%% main routine
\def\snotation#1{
\FPset\Number{#1}
\FPifgt\Number\one
\Powers{#1}
\else
\piconums{#1}
\fi}
\snotation{0.000000100326}
\snotation{1133009.1495978707}
\end{document}
Apologies for the length of the code.
siunitx
can do something very similar using thescientific-notation
andfixed-exponent
settings, I guess.siunitx
!)siunitx
in other parts of the code. These macros though return the numbers in scientific notation automatically from calculations, i.e., you do not need to writenum{1.234e10}
, it takes the number and rather formats automatically. Also sometimessiunitx
does not play well with thefp
package.scientific-notation
option is that you can use it to convert1234000000
into something which is displayed as1.234e10
bysiunitx
. Do tell more about the last point: bug reports are always welcome!