9

Is there any command that allows us to extract the mantissa of a number like 2.36e6 so we can get 2.36?

Something like this:

\mantissa{2.36e6}
2
  • Are you just interested in printing the part before e? Are you interested in performing calculations on this value? Are you sometimes going to supply macros to \mantissa, as in \mantissa{\somevalue}?
    – Werner
    Commented Feb 29, 2016 at 22:37
  • 1
    yes I want to supply macros to \mantissa, as in \mantissa{\somevalue} Commented Mar 1, 2016 at 6:05

3 Answers 3

9

You can extract both the mantissa and the exponent:

\documentclass{article}

\makeatletter
\newcommand{\mantissa}[1]{%
  \hafid@mantissa#1ee\@nil
}
\def\hafid@mantissa#1e#2e#3\@nil{%
  #1%
}
\newcommand{\exponent}[1]{%
  \hafid@exponent#1ee\@nil
}
\def\hafid@exponent#1e#2e#3\@nil{%
  #2%
}

\begin{document}

Mantissa: $\mantissa{1}$; Exponent: $\exponent{1}$\par
Mantissa: $\mantissa{1.2}$; Exponent: $\exponent{1.2}$\par
Mantissa: $\mantissa{1.2e3}$; Exponent: $\exponent{1.2e3}$\par
Mantissa: $\mantissa{1.2e-3}$; Exponent: $\exponent{1.2e-3}$\par

\end{document}

enter image description here

These macros return nothing if the mantissa or the exponent are not present. An easy modification can return 0 if the exponent is not explicitly given: just replace the definition of \hafid@exponent with

\def\hafid@exponent#1e#2e#3\@nil{%
  \ifx\relax#2\relax
    0%
  \else
    #2%
  \fi
}

enter image description here

A version that also allows symbolic input (a control sequence that eventually expands to a number; the exponent can also be input as E.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\mantissa}{m}
 {
  \hafid_mantissa:f { \tl_lower_case:n { #1 } }
 }

\cs_new:Nn \hafid_mantissa:n
 {
  \__hafid_mantissa:www #1 ee \q_stop
 }
\cs_generate_variant:Nn \hafid_mantissa:n { f }

\cs_new:Npn \__hafid_mantissa:www #1 e #2 e #3 \q_stop
 {
  #1
 }

\DeclareExpandableDocumentCommand{\exponent}{m}
 {
  \hafid_exponent:f { \tl_lower_case:n { #1 } }
 }

\cs_new:Nn \hafid_exponent:n
 {
  \__hafid_exponent:www #1 ee \q_stop
 }
\cs_generate_variant:Nn \hafid_exponent:n { f }

\cs_new:Npn \__hafid_exponent:www #1 e #2 e #3 \q_stop
 {
  \tl_if_empty:nTF { #2 } { 0 } { #2 }
 }
\ExplSyntaxOff

\begin{document}

Mantissa: $\mantissa{1}$; Exponent: $\exponent{1}$\par
Mantissa: $\mantissa{1.2}$; Exponent: $\exponent{1.2}$\par
Mantissa: $\mantissa{1.2e3}$; Exponent: $\exponent{1.2e3}$\par
Mantissa: $\mantissa{1.2e-3}$; Exponent: $\exponent{1.2e-3}$\par
Mantissa: $\mantissa{1.2E-3}$; Exponent: $\exponent{1.2E-3}$\par

\newcommand{\mynumber}{1.26e10}

Mantissa: $\mantissa{\mynumber}$; Exponent: \exponent{\mynumber}

\end{document}

enter image description here

Note: due to a misfeature in the current release of expl3 (release 2016/01/19 r6377), the code doesn't work as intended under XeLaTeX or LuaLaTeX. The simplest workaround is not allowing E as a divider:

\DeclareExpandableDocumentCommand{\mantissa}{m}
 {
  \hafid_mantissa:f { #1 }
 }
\DeclareExpandableDocumentCommand{\mantissa}{m}
 {
  \hafid_exponent:f { #1 }
 }
5
  • Interestingly, your code works under pdfLaTeX, but it gives incorrect results under both XeLaTeX and LuaLaTeX. Can some adjustments be made so that the code works under XeLaTeX and LuaLaTeX as well?
    – Mico
    Commented Mar 1, 2016 at 16:26
  • @Mico I think I know what's going wrong (and I blame Joseph for this). ;-)
    – egreg
    Commented Mar 1, 2016 at 16:28
  • @Mico It seems a bug in expl3. The simplest workaround is not allowing E.
    – egreg
    Commented Mar 1, 2016 at 16:45
  • Whilst there's a bug in expl3 here, I'm not sure about using \tl_lower_case:n for this operation. These are programmatic (string) operations not text ones (which the experimental case changer is for). Admittedly, at the moment \str_lower_case:n is not f-type expandable but that can soon be adjusted (it's come up elsewhere so should probably change).
    – Joseph Wright
    Commented Mar 1, 2016 at 17:59
  • @JosephWright I was aware that \tl_lower_case:n is not really the right approach, but \str_lower_case:n isn't either, even if it was f-expandable, because this would require producing a stringified e for the argument delimiter. Doable, but awkward.
    – egreg
    Commented Mar 1, 2016 at 18:52
11

You can extract the components (mantissa or exponent) using TeX parameter text matching:

enter image description here

\documentclass{article}

\makeatletter
\def\@mantissa#1e#2\relax{#1}
\def\@exponent#1e#2\relax{#2}
\newcommand{\mantissa}[1]{\expandafter\@mantissa#1\relax}
\newcommand{\exponent}[1]{\expandafter\@exponent#1\relax}
\makeatother

\begin{document}
\setlength{\parindent}{0pt}% Just for this example

\newcommand{\Value}{2.36e6}

Value: \Value

Mantissa: \mantissa{\Value}

Exponent: \exponent{\Value}

\end{document}

The "non-user level" macros \@mantissa and \@exponent expects a parameter text of the form <m>e<e>\relax where e and \relax are required in the input stream. The user level macros \mantissa and \exponent both pass \relax, but that means you can only pass numbers/values that uses scientific notation, and therefore necessarily have the notation <m>e<e>.

5

Just for the sake of variety, here's a LuaLaTeX-based solution.

The following code sets up two Lua functions, named get_mant and get_expo, which extract the mantissa and the exponent, respectively, from a term such as -1.23e+45. The code also provides two TeX "wrapper" macros, named \GetMant and \GetExpo, which invoke the Lua functions. Thus, \GetMant{2.36e6} returns 2.36, and \GetExpo{2.34e-56} returns -56.

It is assumed that the inputs of \GetMant and \GetExpo are either valid numbers expressed in "scientific" notation or macros that evaluate to valid scientific-notation numbers. The code doesn't perform any input sanity checking, though: It assumes that you won't be trying to extract mantissas and exponents from expressions such as abcdefghi or +55+e-66-d. The main formatting requirement is that the input string contains one (and only one) instance of the letter e; E is OK too.

Two comments:

  • The code is set up to suppress any + symbols that may be present at the start of the mantissa and exponent components. If you do want to preserve the + symbols, just remove the tonumber function calls in the arguments of tex.sprint.

  • The code can handle the case of an "empty mantissa", i.e., an expression such as e22: In such an event, the mantissa is set to 1. Similarly, the code can also handle the case of an "empty exponent", i.e., an expression such as 1.6e: the exponent is set to 0. Even the extreme (and frankly somewhat absurd) empty mantissa/empty exponent case, viz., e or E, is handled correctly: the mantissa is set to 1 and the exponent is set to 0. :-)

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{booktabs}

%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function get_mant ( s )
  mant = string.gsub ( s, "^(.-)[eE](.-)$", "%1" ) 
  if mant == "" then mant = "1" end
  return tex.sprint ( tonumber(mant) )
end
function get_expo ( s )
  expo = string.gsub ( s, "^(.-)[eE](.-)$", "%2" )
  if expo == "" then expo = "0" end
  return tex.sprint ( tonumber(expo) )
end
\end{luacode}

%% TeX-side code
\newcommand\GetMant[1]{\directlua{get_mant(\luastring{#1})}}
\newcommand\GetExpo[1]{\directlua{get_expo(\luastring{#1})}}

\begin{document}

\newcommand{\NumA}{-3.45e-678}
\newcommand{\NumB}{+1.23E+45}
\newcommand{\NumC}{e}

$\begin{array}{@{}lll@{}}
\mbox{Input} & \mbox{Mantissa} & \mbox{Exponent}\\
\midrule
\texttt{\NumA} & \GetMant{\NumA} & \GetExpo{\NumA}\\
\texttt{\NumB} & \GetMant{\NumB} & \GetExpo{\NumB}\\
\texttt{e22}   & \GetMant{e22}   & \GetExpo{e22}  \\
\texttt{1.23E} & \GetMant{1.23E} & \GetExpo{1.23E}\\
\texttt{\NumC} & \GetMant{\NumC} & \GetExpo{\NumC}\\
\end{array}$

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .