# Getting length as number?

I have probably formulated the question wrong, as I don't know the Tex internals - but this is what I mean; consider this example:

\newcommand{\myNum}{2}
\newlength{\myLength}
\setlength{\myLength}{\myNum cm}


Here, I'd consider \myNum to represent a 'numeric variable', and \myLength a Tex length (i.e. a number and a unit); and so I'd consider the above example a "conversion" from numeric to length "variable".

Is it possible to do the other way around? I.e. if \myLength is given to be 2 cm, is there a command that will "get"/"extract" the numeric value only? I'd imagine doing something like this (pseudocode):

\newcommand{\myNum}{\getlength{\myLength}}


... after which, \myNum would have value "2" ...

Does anything like this exist?

EDIT: I guess I need something similar to \the which is for counters ... ?!

• \the\myLength gives you the dimension, I don't know how you'd extract just the number... If you wanted to do something like this, I expect the calc package might be useful. Or possibly this package Apr 5, 2011 at 10:53
• Thanks for noting that, @Seamus - I was not aware \the could be applied to lengths too (try searching for "latex \the", hehe :) ); \theMyLength indeed prints the length, but seemingly in pt units. Apr 5, 2011 at 10:56

You can remove the pt unit from the length using \strip@pt as shown below. I you want the number in cm you would have to convert it by yourself.

\documentclass{article}

\makeatletter
\newcommand*{\getlength}[1]{\strip@pt#1}
% Or rounded back to cm (there will be some rounding errors!)
%\newcommand*{\getlength}[1]{\strip@pt\dimexpr0.035146\dimexpr#1\relax\relax}

\makeatother

\begin{document}

Test: \getlength{\textwidth}  % Result: 345

\end{document}


Another alternative which is more flexible and also allows you to store the resulting number in a macro is to use pgfmath (pgf package). It also allows you to easily convert the number to cm:

\documentclass{article}

\usepackage{pgf}
\newcommand*{\getlength}[2]{%
\pgfmathsetmacro#1{#2}%  Result in pt
% Or:
%\pgfmathsetmacro#1{0.0351459804*#2}%  Result in cm
}

\begin{document}

\getlength{\myNum}{\textwidth}

Test: \myNum % Result: 345.0

\end{document}


There is also the round( ) function for pgfmath which allows you to round the number, e.g. to two fractional digits. The trick is to multiple it with 100 before the rounding and divide it afterwards by 100.

\documentclass{article}

\usepackage{pgf}
\newcommand*{\getlength}[2]{%
% Convert to cm and round to two fractional digits:
\pgfmathsetmacro#1{round(3.51459804*#2)/100.0}%
}

\begin{document}

\setlength{\textwidth}{2.123cm}
\getlength{\myNum}{\textwidth}

Test: \myNum% Gives 2.12

\setlength{\textwidth}{2cm}
\getlength{\myNum}{\textwidth}

Test: \myNum% Gives 2.0

\end{document}


The fractional part (like .0) can be avoided by using \pgfmathtruncatemacro instead of \pgfmathsetmacro, but I don't think you need that.

• Fantastic - thanks for the fast response, @Martin Scharrer! Apr 5, 2011 at 10:57
• @sdaau: Minor note about the pgfmath round function: I wouldn't rely on the "multiply by 100, round, divide by 100" method. I tried it recently and found that the accuracy was quite poor. Apr 5, 2011 at 11:16
• Thanks @Andrew. An alternative would be to truncate the digits instead: \def\twofracdigits#1.#2#3#4\relax{#1.#2#3} \newcommand*{\getlength}[2]{% \pgfmathsetmacro#1{0.0351459804*#2}% \edef#1{\expandafter\twofracdigits#1\empty\empty\relax}% }. However the OP might not need this at all. Apr 5, 2011 at 11:40
• @sdaau: I've just tried the example where I got the inaccuracy and I can't reproduce it. So I think I'd like to downgrade my warning a bit to just: "be careful". However, I would recommend using the \pgfmathprintnumber command (see the pgf manual for more details) instead of the "multiply, round, divide" cycle. Apr 5, 2011 at 11:40
• @Martin: I think it's new in 2.10. Apr 5, 2011 at 11:42

An alternative to Martin's approach is to use TeX's \number primitive, which will give you the underlying integer value in sp

\documentclass{article}

\newcommand*\getlength[1]{\number#1}

\begin{document}

Test: \getlength{\textwidth}

\end{document}


(TeX does everything in integers, more or less, so lengths are actually stored in sp, which are tiny length units. Everything else is an integer multiple of a value in sp.)

• Damn: I was 49 seconds slower. Apr 5, 2011 at 11:03
• @Bruno: Ah well :-) Apr 5, 2011 at 11:04
• Thanks for that @Bruno Le Floch & @Joseph Wright - great to know that primitive! (Also thanks for the note on internal storage in Tex) Apr 5, 2011 at 11:10
• +1 Just as a reference: 65536 sp = 1 pt Apr 5, 2011 at 11:24
• And if needed you can use the fp package to do calculations with floating point numbers. Apr 5, 2011 at 17:20

One can use xfp:

\documentclass{article}
\usepackage{xfp}

\NewExpandableDocumentCommand{\getlengthnumber}{O{pt}m}{%
% #1 (optional, default pt), #2 = length
\fpeval{(#2)/(1#1)}%
}

\begin{document}

\getlengthnumber{\textwidth}

\getlengthnumber[cm]{\textwidth}

\getlengthnumber[cm]{1in}

\getlengthnumber[sp]{1pt}

\end{document}


The big advantage over the pgf methods is that this is fully expandable.

Here I would like to provide a simple solution with pgf

% !Mode:: "TeX:UTF-8"
\documentclass{article}
\usepackage{pgf}

\begin{document}
\noindent
\the\textwidth \\
\pgfmathparse{\textwidth}
\pgfmathresult \\
\end{document}


where \the\textwidth prints the length with units, while \pgfmathparse returns \textwidth without unit to \pgfmathresult

there are many more functions to choose from section Mathematical Expressions in pgf manual.

• Did you try \usepackage{xfp} and then \fpeval(\textwidth}? By the way, your method is already covered in Martin Scharrer's answer. May 2, 2020 at 9:03
• @egreg Thanks, \fpeval(\textwidth} is also a nice solution. As for the second point, although we both used pgf, he used \pgfmathsetmacro and I used \pgfmathparse.
– zyy
May 2, 2020 at 13:49