This is an interesting question. First we need to compare and analyse some answers
1) With Lua : This is the future and it's very accurate but unfortunately it's not enough used and a lot of TeX's users works only with pdf(la)TeX.
2) fp
solution is fine but we need to use it with precaution because this can be slow. It's the method that I prefer.
But a problem can arrive with fp
if you need to get the result of (-1.5)^(2)
.
The next code is from Christian Tellechea 2009 modified by me.
\documentclass{scrartcl}
\usepackage{fp}
\makeatletter
\def\FP@pow#1#2#3{%
\FP@beginmessage{POW}%
{\def\FP@beginmessage##1{}%
\def\FP@endmessage##1{}%
\FPifzero{#2}%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\FP@pow@zero{#3}}%
{\FPifint{#3}%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\FPifneg{#2}%
\FPneg\FP@tmpd{#2}%
\FPln\FP@tmpd\FP@tmpd
\FPmul\FP@tmpd\FP@tmpd{#3}%
\FPexp\FP@tmpd\FP@tmpd
\FPtrunc\FP@tmp{#3}0%
\ifodd\FP@tmp
\FPneg\FP@tmp\FP@tmpd
\else
\let\FP@tmp\FP@tmpd
\fi
\else
\FPln\FP@tmpd{#2}%
\FPmul\FP@tmpd\FP@tmpd{#3}%
\FPexp\FP@tmp\FP@tmpd
\fi
}%
{\FPln\FP@tmpd{#2}%
\FPmul\FP@tmpd\FP@tmpd{#3}%
\FPexp\FP@tmp\FP@tmpd}%
}%
\global\let\FP@tmp\FP@tmp}%
\FP@endmessage{}%
\let#1\FP@tmp}
\makeatletter
\begin{document}
\FPpow\temp{-1.5}{2}
\temp
\FPpow\temp{-2}{3}
\temp
\end{document}
3) pgfmath
. The Martin's answer describes the traditional method. It can also be slow and sometimes inaccurate for extreme values. The next picture is to illustrate inaccurate results sometimes with pgfmath
. The picture comes from the pgfmanual in the paragraph The Syntax of Projection Modifiers. The intersections of the three altitudes are fine with small sizes but with a big zoom we get this :

4) with fpu
. It's possible to use fpu
It's a package inside pgf
.
\documentclass{article}
\usepackage{tikz}
\usepackage{fp}
\usetikzlibrary{fpu}
\newlength{\lengtha}
\newlength{\lengthb}
\begin{document}
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\setlength{\lengtha}{1pt}
\setlength{\lengthb}{1pt}
\pgfmathparse{sqrt(\lengtha*\lengtha + \lengthb*\lengthb)}
\pgfmathresult
\end{document}
The result is 1.414192000000000. This strange because pgfmath
in this case gives 1.41421 while fp
with the same values gives 1.414213562373095042.
5) \usetikzlibrary{fixedpointarithmetic}
Another possibility is the fixed point arithmetic
. It's again inside pgf
\documentclass{article}
\usepackage{tikz}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\newlength{\lengtha}
\newlength{\lengthb}
\begin{document}
\setlength{\lengtha}{1pt}
\setlength{\lengthb}{1pt}
\pgfkeys{/pgf/fixed point arithmetic={scale results=10^-6}}
\pgfmathparse{sqrt(\lengtha*\lengtha + \lengthb*\lengthb)}
\pgfmathresult
\end{document}
The result is as with fp
, it's normal fp
is used !! result = 1.414213562373095042
6) \usepackage{tkz-euclide}
When you need to calculate the distance between two nodes, you can use a macro that I define in my package: tkz-euclide
. It's a mix with fp
.
\begin{tikzpicture}
\coordinate (A) at (3,0);
\coordinate (B) at (0,4);
\tkzCalcLength[cm](A,B)
\node {\tkzLengthResult } ;
\draw (A) circle (\tkzLengthResult cm) ;
\draw[fill=red] (A) circle (2pt) ;
\draw[fill=red] (B) circle (2pt) ;
\end{tikzpicture}
\tkzLengthResult
gives 5.00000 There is an option to get the result in pt or in cm.
7) Finally the last solution used TeX
. This solution has been written by a friend J_C Charpentier. This is interesting. The macro is named \pythagore
and this macro uses another macro \SQRT
to get the square root of an integer < 1962446671 .
\documentclass{article}
\makeatletter
\newcount\@tempcntc
\newcommand\SQRT[2]{%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% #2 = \sqrt{#1} (valeur entière) %
% #2 est une longueur %
% #1 ne doit pas dépasser 1962446671 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialisations
\@tempcnta #1\relax % Sauvegarde valeur
\@tempcntb 1 % juste pour le premier test
\@tempcntc #1\relax % Terme en cours
% simili racine pour le premier terme !!!!
\ifnum \@tempcntc > 1073741824 % 2^{30}
\divide \@tempcntc 32738
\else\ifnum \@tempcntc > 268435456 % 2^{28}
\divide \@tempcntc 16384
\else\ifnum \@tempcntc > 67108864 % 2^{26}
\divide \@tempcntc 8192
\else\ifnum \@tempcntc > 16777216 % 2^{24}
\divide \@tempcntc 4096
\else\ifnum \@tempcntc > 4194304 % 2^{22}
\divide \@tempcntc 2048
\else\ifnum \@tempcntc > 1048576 % 2^{20}
\divide \@tempcntc 1024
\else\ifnum \@tempcntc > 262144 % 2^{18}
\divide \@tempcntc 512
\else\ifnum \@tempcntc > 65536 % 2^{16}
\divide \@tempcntc 256
\else\ifnum \@tempcntc > 16384 % 2^{14}
\divide \@tempcntc 128
\else\ifnum \@tempcntc > 4096 % 2^{12}
\divide \@tempcntc 64
\else\ifnum \@tempcntc > 1024 % 2^{10}
\divide \@tempcntc 32
\else\ifnum \@tempcntc > 256 % 2^{8}
\divide \@tempcntc 16
\else\ifnum \@tempcntc > 64 % 2^{6}
\divide \@tempcntc 8
\else\ifnum \@tempcntc > 16 % 2^{4}
\divide \@tempcntc 4
\else\ifnum \@tempcntc > 4 % 2^{2}
\divide \@tempcntc 2
\else\ifnum \@tempcntc > 2 % 2^{1}
% c'est 3 ou 4, l'arrondi est toujours 2
\@tempcntc 2
\@tempcntb 0 % pas de boucle !
\else\ifnum \@tempcntc > 1
% C'est 2, l'arrondi est 1
\@tempcntc 1
\@tempcntb 0 % pas de boucle !
\else
% c'est 0 ou 1 la racine est le nombre
\@tempcntb 0 % pas de boucle !
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi % joli !
% Boucle principale (Newton)
\loop
\ifnum\@tempcntb>0
% Calcul du terme suivant
\@tempcntb \@tempcnta
\divide \@tempcntb \@tempcntc
\advance \@tempcntc \@tempcntb
\divide \@tempcntc 2
% On regarde où on en est
% (différence entre l'itération au carré et le nombre initial)
\@tempcntb \@tempcntc
\multiply \@tempcntb \@tempcntb
\advance \@tempcntb -\@tempcnta
\repeat
% Sauvegarde du résultat
#2\the\@tempcntc sp\relax
}
\newcommand*\pythagore[3]{%
\dimen0=#1\relax
\@tempcnta \dimen0
\dimen0=#2\relax
\@tempcntb \dimen0
% Pour éviter les débordements
% on travaille en 1/32 de point
\divide \@tempcnta 2048
\divide \@tempcntb 2048
% calcul de a*a+b*b
\multiply \@tempcnta \@tempcnta
\multiply \@tempcntb \@tempcntb
\advance \@tempcnta \@tempcntb
% appel de la racine
\SQRT{\the\@tempcnta}{#3}%
% Fin des débordements !
#3 2048#3\relax
}
\makeatother
\newlength{\result}
\begin{document}
\pythagore{2pt}{2pt}{\result}
\the\result
\pythagore{3pt}{4pt}{\result}
\the\result
\pythagore{6pt}{8pt}{\result}
\the\result
\end{document}
Results are : 2.8125pt ; 5.0 pt and 10.0pt
I think the easiest way to calculate this is yshift={-3*(mod(#2-1,6)+1)*1cm}
, which also works for chapters 13, 14, etc.
\mod(a,b)
gives the remainder of the division of a by b. So mod(#2-1,6)
will give 0,1,2,3,4,5,0,1,2,... for #2
=1,2,3,...
See chapter 63.2 in the v2.10 TikZ manual for a list of functions that are available to do calculations within TikZ (for example it has ifthenelse
).
Best Answer
The calculation are for intergers only. You should multiply
#1
by 100 first.And it is easier to use eTeX:
If you need more precise solution, or the input is not interger values, you can use
fp
,fltpoint
,pgfmath
orl3fp
packages for this. For example: