If the output of a macro is fully expandable I would store it in another macro which is also written to the .aux file. The name of that storage macro should be generic so that the calculation macro can test if it exists and use simply reuse it if so. You could use MD5 checksums calculated from the input as part of the macro names if the input is something which would cause issues inside \csname ... \endcsname, but for e.g. numbers this isn't necessary.
Using your Mersenne calculation as example:
\documentclass{article} \usepackage[english]{babel} \usepackage{numprint} \usepackage{bigintcalc} \begin{document} \npthousandsep{ } \makeatletter \def\Mersenne#1{% \begingroup \par\noindent\parindent=0pt $M_{#1}=$\par % Calculate if not defined yet \@ifundefined{Mersenne@#1}{% \def\exponent##1{\bigintcalcPow{2}{##1}}% \expandafter\xdef\csname Mersenne@#1\endcsname{% \bigintcalcSub{\exponent{#1}}{1}% }% }{}% % Write to aux file \immediate\write\@auxout{\noexpand\expandafter\gdef\noexpand\csname Mersenne@#1\noexpand\endcsname{\csname Mersenne@#1\endcsname}}% % Print \expandafter\numprint\expandafter{\csname Mersenne@#1\endcsname}% \endgroup } \makeatother \Mersenne{1279} \end{document}
The .aux file then contains the following line and future recalculations are avoided as long the .aux isn't deleted or not written properly due to a compilation error:
\expandafter \gdef \csname Mersenne@1279\endcsname {10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087}
If the the output of the macro is not fully expandable or even fragile (i.e. \edef would cause errors) it might be stored inside a box register instead. But this has several drawbacks: It can't be stored in the .aux file easily so the reuse is limited for several usages of the same macro in one compilation run. Also the typesetting is then fixed and e.g. the line breaking for long numbers won't be specific for each usage.