6

The MWE below suggests that truncating an fp type number is not just for cosmetics but actually changes the number's value. Is there a way to reduce the number of decimals displayed without affecting the number's full accuracy in computations? I browsed through siunitx but nothing jumped at me.

\documentclass{article}
% RN. 6 April 2017
% TOPIC:
%  Truncating floating point numbers 
%=======================
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
%-----------------------
\ExplSyntaxOn
\NewDocumentCommand\myTruncatingFloatingPoints{mO{3.11998}O{3.0198}}
  {
    \fp_eval:n {trunc(#2,#1)*trunc(#3,#1)}
  }  %  \myTruncatingFloatingPoints

\ExplSyntaxOff
%-----------------------
\begin{document}
    1. Full complement of digits:~\myTruncatingFloatingPoints{5}

    2. Truncated to 2 decimal digits:~  \myTruncatingFloatingPoints{2}
\end{document}
  • 1
    Why not use a second variable? Assign the value of the first to the second and truncate that one for printing. This way you can calculate with the first one with full accuracy. (might be an ugly workaround) – Skillmon Apr 06 '17 at 09:41

3 Answers3

8

Taken from How to set the precision in numbers (there are more versions, have a look):

\documentclass{article}
\usepackage{siunitx}
\begin{document}
\num{0.12368455}

\num[round-mode=places,round-precision=4]{0.12368455}
\end{document}

Is that what you are looking for?

5

Here I use \num just for pretty printing.

\documentclass{article}
\usepackage{siunitx,xfp}

\begin{document}

\begin{tabular}{ll}
No truncation  & \num{\fpeval{3.11998*3.0198}} \\
Truncation     & \num{\fpeval{trunc(3.11998*3.0198,2)}} \\
Bad truncation & \num{\fpeval{trunc(3.11998,2)*trunc(3.0198,2)}}
\end{tabular}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Truncating the result only is the obvious thing to do, except that I wanted truncated versions of the operands, say for instance as elements of a matrix, then do operations with full accuracy ... Anyway, we have had answers. – Reinhard Neuwirth Apr 06 '17 at 22:37
  • 1
    @ReinhardNeuwirth I'm afraid I don't understand; computations are distinct from printing the result. – egreg Apr 06 '17 at 22:57
  • You are quite right! It seems I got myself into a muddle here. – Reinhard Neuwirth Apr 07 '17 at 09:32
4

Because I felt like reinventing the wheel...(again)

EDITED so that truncating to 0 places does not present the decimal.

RE-EDITED to handle negative numbers.

\documentclass{article}
\newcounter{digits}
\newcommand\myTruncatingFloatingPoints[2]{%
  \whole{#1}#2..\relax%
}
\def\whole#1#2.#3.#4\relax{%
    \presentwhole#2\relax\relax%
    \ifx\relax#3\relax.\trunc{#1}00\relax\else%
      \ifnum#1>0\relax.\trunc{#1}#3\relax\fi%
    \fi%
}
\def\presentwhole#1#2\relax{%
  \ifx-#1\ensuremath{-}\the\numexpr0#2\else\the\numexpr0#1#2\fi%
}
\def\trunc#1#2#3#4\relax{%
  \setcounter{digits}{#1}%
  \addtocounter{digits}{-1}%
  \ifnum\thedigits>0\relax%
    #2%
    \trunc{\thedigits}#3#40\relax%
  \else%
    \ifnum#3<5\relax#2\else\the\numexpr#2+1\relax\fi% ROUNDED
%    #2% TRUNCATED
  \fi%%  \fi%
}
\begin{document}
1. \makebox[.8in][r]{9.421715604} to 5 digits: \myTruncatingFloatingPoints{5}{9.421715604}

2. \makebox[.8in][r]{9.421715604} to 3 digits: \myTruncatingFloatingPoints{3}{9.421715604}

3. \makebox[.8in][r]{9.421715604} to 1 digits: \myTruncatingFloatingPoints{1}{9.421715604}

4. \makebox[.8in][r]{9.421715604} to 0 digits: \myTruncatingFloatingPoints{0}{9.421715604}

5. \makebox[.8in][r]{29} to 2 digits: \myTruncatingFloatingPoints{2}{29}

6. \makebox[.8in][r]{.1275} to 3 digits: \myTruncatingFloatingPoints{3}{.1275}

7. \makebox[.8in][r]{.1275} to 4 digits: \myTruncatingFloatingPoints{4}{.1275}

8. \makebox[.8in][r]{$-$.12} to 6 digits: \myTruncatingFloatingPoints{6}{-.12}
\end{document}

enter image description here