The next code gives : 1 1.2 3
But 1 2.2 5.2 is expected. What is wrong ?
\documentclass[tikz]{standalone}
\begin{document}
\xdef\Sum{0}
\foreach \i in {1,1.2,3} {
\pgfmathsetmacro\Sum{\Sum+\i}
\Sum\ }
\end{document}
The next code gives : 1 1.2 3
But 1 2.2 5.2 is expected. What is wrong ?
\documentclass[tikz]{standalone}
\begin{document}
\xdef\Sum{0}
\foreach \i in {1,1.2,3} {
\pgfmathsetmacro\Sum{\Sum+\i}
\Sum\ }
\end{document}
It seems like the definition of the macro \Sum is local to the group. At the next iteration, its content is forgotten and only the first global definition with \xdef is kept. I don't know much about it though.
Here is a working example (but probably not the best way to do it).
\documentclass[tikz]{standalone}
\begin{document}
\xdef\Sum{0}
\foreach \i in {1,1.2,3} {
\xdef\Sum{\Sum+\i}
\pgfmathparse{\Sum}\pgfmathresult\ }
\end{document}
The output is as expected: 1.0 2.2 5.2
With expl3:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\sumlist{ m }
{
\tarass_sum_list:n { #1 }
}
\fp_new:N \l__tarass_partial_sum_fp
\cs_new_protected:Npn \tarass_sum_list:n #1
{
\fp_zero:N \l__tarass_partial_sum_fp
\clist_map_inline:nn { #1 }
{
\fp_add:Nn \l__tarass_partial_sum_fp { ##1 }
$\fp_use:N \l__tarass_partial_sum_fp$
\ %
}
\unskip % remove the last space
}
\ExplSyntaxOff
\begin{document}
\sumlist{1,1.2,3}
\sumlist{1,-1.2,3}
\end{document}

Here is a version which will print the sum exactly with the number of necessary digits.
Hmm... that was not what was asked.Sorry.
Ok, so I update the code to do the printing of partial sums which was asked for. As has been pointed out the issue with \foreach is one of local groups limiting the scope. The \xintFor loop from xinttools does not have this issue. And thus I use it here. While I am at it I use the arithmetics of xintfrac package. But the \xintFor loop could have been used with pgfmath as math engine.
Then, the second element which I earlier had focused on is the printing of a decimal number with exactly the number of digits needed. Notice that the macros here are compatible with arbitrarily long numbers.
Code:
\documentclass{article}
\usepackage{xintfrac}
\usepackage{xinttools}
% Let's first do the partial sums as fixed point numbers.
% We hardcode \Sum macro to hold the partial sums
\newcommand\TarassSumList [1]{\def\Sum{0}\xintFor ##1 in {#1}\do
{\oodef\Sum{\xintAdd{\Sum}{##1}}%
\xintRound{4}{\Sum}%
\xintifForLast{}{, }}}
% let's now do it again but printing with the number of necessary
% digits:
%
% We abstract some command from code below (an expandable version
% should be added to xint package)
\makeatletter
\def\ReduceDec@helper #1[#2]{#2}% duplicate of \sumlist@helper
\newcommand\ReduceDec [1]{%
\oodef\ReduceDec@X {\xintREZ{#1}}%
\oodef\ReduceDec@N {\expandafter\ReduceDec@helper\ReduceDec@X }%
\ifnum\ReduceDec@N<\z@
\oodef\ReduceDecResult{\xintTrunc {-\ReduceDec@N}{\ReduceDec@X}}%
\else
\oodef\ReduceDecResult{\xintNum \ReduceDec@X}%
\fi }
\makeatother
\newcommand\TarassSumListB [1]{\def\Sum{0}\xintFor ##1 in {#1}\do
{\oodef\Sum{\xintAdd{\Sum}{##1}}%
\ReduceDec{\Sum}\let\Sum\ReduceDecResult
\Sum
\xintifForLast{}{, }}}
% earlier answer which concentrated on the printing of decimal number with
% exactly the needed number of digits.
% sum decimal numbers, and print the result with exactly as
% many digits as necessary after the decimal mark
% It would be quite easier to print a truncation or rounding to a
% given number of digits after decimal mark (\xintTrunc or \xintRound
% and the whole thing would be completely expandable)
% To avoid scaring people, I did not make this more challenging version
% expandable...
% And it is to be used only for decimal numbers or scientific number on
% input, no fractions like 3/7.
\makeatletter
\def\sumlist@helper #1[#2]{#2}% there should be a macro in xintfrac for that
\newcommand\sumlist [1]{%
\oodef\sumlist@S {\xintREZ{\xintSum{\xintCSVtoList {#1}}}}%
\oodef\sumlist@N {\expandafter\sumlist@helper\sumlist@S }%
\ifnum\sumlist@N<\z@
\xintTrunc {-\sumlist@N}{\sumlist@S}%
\else
\xintNum \sumlist@S
\fi}
\makeatother
\begin{document}\thispagestyle{empty}
Fixed point numbers (4 decimal digits):
\TarassSumList{1,1.2,3}
\TarassSumList{1,-1.2,3}
\TarassSumList {1.23, 3.31, -0.54}
\TarassSumList {1.234, 5.6789, 3.211768, -17.28929}
\TarassSumList {1.234, 5.6789, 3.211768, -17.28929, 13.004622}
\TarassSumList {1.23e-3, 3.25e-3, 17.123e-4}
Numbers with as many digits as necessary:
\TarassSumListB{1,1.2,3}
\TarassSumListB{1,-1.2,3}
\TarassSumListB {1.23, 3.31, -0.54}
\TarassSumListB {1.234, 5.6789, 3.211768, -17.28929}
\TarassSumListB {1.234, 5.6789, 3.211768, -17.28929, 13.004622}
\TarassSumListB {1.23e-3, 3.25e-3, 17.123e-4}
% \sumlist{1,1.2,3}
% \sumlist{1,-1.2,3}
% \sumlist {1.23, 3.31, -0.54}
% \sumlist {1.234, 5.6789, 3.211768, -17.28929}
% \sumlist {1.234, 5.6789, 3.211768, -17.28929, 13.004622}
% \sumlist {1.23e-3, 3.25e-3, 17.123e-4}
% \sumlist {100, 200}
\end{document}
Tikz groups the loop body of \foreach, making macro definitions local. Package pgfplots provides a non-grouping variant:
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\begin{document}
\def\Sum{0}
\pgfplotsforeachungrouped \i in {1,1.2,3} {
\pgfmathsetmacro\Sum{\Sum+\i}
\Sum\ }
\end{document}
Just practice with Asymptote using a built-in sum(a) function to calculate the sum of all elements of a given array of real number a.
real[] a={1,1.2,-5};
write(a);
real T=sum(a);
write("The sum of all elements is");
write(T);
\foreachstatement is carried out in a new group. See thepgfmanual for more information. – May 21 '14 at 13:29pgfplotsprovides a non-grouping variant. – AlexG Apr 12 '22 at 08:20