How can I round numbers relative to their order of magnitude?

This is a question which came up in the answer https://tex.stackexchange.com/a/183227/1537 .

Suppose we have a sequence of numbers for which we know that they are the log of some quantity. Now I want to compute exp of the input value and format the result in some cool way. How can I avoid rounding inaccuracies such that it fits all numbers in the sequence?

Let us assume that the problem is stated as

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}

\begin{document}
\thispagestyle{empty}

% use \newcommand (not \def), so the one (and only)
% argument can be specified in {} (and not in []) brackets
\newcommand{\mynum}[1]{
% =\pgfmathparse{e^\tick}\pgfmathresult : ! Dimension too large. ; - use exp(x)
\pgfkeys{/pgf/fpu}% else dimension too large!
\pgfmathparse{exp(#1)}%
\pgfmathfloattofixed\pgfmathresult
\pgfmathresult
}

\message{^^J}

\mynum{-0.69316}

\mynum{0.0}

\mynum{1.60942}

\mynum{2.30258}

\mynum{3.912}

\mynum{4.60516}

\mynum{6.21458}

\mynum{6.90775}

\mynum{8.51717}

\mynum{9.21033}

\mynum{10.81975}

\mynum{11.51291}
\end{document}


Ideally, each number would be rounded to a relative accuracy of, say, 3 digits - but relative to the number as such.

The key is to employ /pgf/number format/fixed relative which determines the accuracy relative to the current number and generates a fixed-point number as result.

This return value makes use of \pgfmathprintnumberto[..., verbatim] to stress that the resulting macro \tmp contains a standard fixed point number which is not formatted (i.e. does not contain math-mode stuff like {,}) and can be used as input to other number formatters. The original question in https://tex.stackexchange.com/a/183227/1537 relied on siunitx.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}

\begin{document}
\thispagestyle{empty}

% use \newcommand (not \def), so the one (and only)
% argument can be specified in {} (and not in []) brackets
\newcommand{\mynum}[1]{
% =\pgfmathparse{e^\tick}\pgfmathresult : ! Dimension too large. ; - use exp(x)
\pgfkeys{/pgf/fpu}% else dimension too large!
\pgfmathparse{exp(#1)}%
\pgfmathfloattofixed\pgfmathresult
\message{exp(#1) = \pgfmathresult^^J}%
\pgfmathprintnumberto[
% it is rounded relative to its (individual!) order of
% magnitude:
fixed relative,
% ... and with three digits relative to its order of
% magnitude. This should avoid rounding problems
% since it is applied to each tick number
% individually.
precision=3,
verbatim,
]{\pgfmathresult}{\tmp}%
\message{fixed realtive=\tmp^^J}%
\tmp
}

\message{^^J}

\mynum{-0.69316}

\mynum{0.0}

\mynum{1.60942}

\mynum{2.30258}

\mynum{3.912}

\mynum{4.60516}

\mynum{6.21458}

\mynum{6.90775}

\mynum{8.51717}

\mynum{9.21033}

\mynum{10.81975}

\mynum{11.51291}
\end{document}


The console output is

exp(-0.69316) = 0.50012
fixed realtive=0.5
exp(0.0) = 1.0000000000
fixed realtive=1
exp(1.60942) = 4.99974000000000
fixed realtive=5
exp(2.30258) = 10.000000000
fixed realtive=10
exp(3.912) = 49.9974000000000
fixed realtive=50
exp(4.60516) = 100.00000000
fixed realtive=100
exp(6.21458) = 499.974000000000
fixed realtive=500
exp(6.90775) = 1000.0000000
fixed realtive=1000
exp(8.51717) = 4999.74000000000
fixed realtive=5000
exp(9.21033) = 10000.000000
fixed realtive=10000
exp(10.81975) = 49997.4000000000
fixed realtive=50000
exp(11.51291) = 100000.00000
fixed realtive=100000

• Minor typo in first word. (Not worth editing on its own for sure!)
– cfr
Jun 8, 2014 at 23:28
• Thanks; I've corrected it. Feel free to edit any typos, I appreciate the effort. Jun 9, 2014 at 7:14