# 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 – Seamus Apr 5 '11 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. – sdaau Apr 5 '11 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! – sdaau Apr 5 '11 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. – Loop Space Apr 5 '11 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. – Martin Scharrer Apr 5 '11 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. – Loop Space Apr 5 '11 at 11:40
@Martin: I think it's new in 2.10. – Loop Space Apr 5 '11 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. – Bruno Le Floch Apr 5 '11 at 11:03
@Bruno: Ah well :-) – Joseph Wright Apr 5 '11 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) – sdaau Apr 5 '11 at 11:10
+1 Just as a reference: 65536 sp = 1 pt – Martin Scharrer Apr 5 '11 at 11:24
And if needed you can use the fp package to do calculations with floating point numbers. – Bruno Le Floch Apr 5 '11 at 17:20