I am searching for a simple way of rounding and setting an input to a desired number of significant figures. There are a vast number of posts that discuss similar problems, but none address this issue. I turned to writing my own function. Here it is below:
SigFig[x_, n_] :=
(p := Solve[10^i <= Abs[x] < 10^(i + 1), i, Integers][[1, 1, 2]];
N[Round[x, 10^(p - n + 1)], n]) // Quiet
SigFig rounds any real number x (of magnitude greater than or equal to 1) to a specified number of significant figures n.
Obviously the biggest flaw in this function is not catering for numbers of magnitude less than 1, and thus also the problem of preceeding insignifcant zeroes such as 0.00123. Admittedly it works for my specific application as all my numbers are between 1 and 10000; so honestly I can't be bothered trying to make it universal due to time constraints.
So, is there a simple pre-defined function or simple way of doing such a simple task that I have completely missed? I ultimately would like to know of a simple significant figure rounding function that works all the time and is much less complicated than what I've given here. I believe that if no such solution exists, then (1) a solution for this task needs to be documented so that people can search for it and (2) the shortcoming in lack of said function needs to be addressed to Wolfram Research. Does anyone have any suggestions on a pre-defined, pre-established or a custom function of their own that improves upon my current suggestion?
Answer
Please tell me if this simplified function does what you want:
f[x_, n_] := Round[x, 10^(1 - n + ⌊ Log10 @ Abs @ x ⌋)] ~SetPrecision~ n
Test:
Table[f[x*Pi, 4], {x, {1/100, 1/10, 1, 10, 100}}]
% // FullForm
{0.03142, 0.3142, 3.142, 31.42, 314.2}
List[0.03142`4., 0.3142`4., 3.142`4., 31.42`4., 314.2`4.]
Update
The OP wrote:
I understand that there is a difference in the 'implied precision' between the number
0.5and1/2when entered in Mathematica. But my request is to perform a very simple calculation: consider the number1.004and double it. The answer is2.008. Then round it to 3 sig. fig, the answer is 2.01. Take that number, divide it by two/multiply by half/multiply by 0.5 (mathematically equivalent). The mathematical answer is 1.005. I did not ask to round the final answer to 3 sig. fig. as that could be done by doingfto the final answer. Is this possible?
I suspect that I am failing to comprehend the needs that are behind this request and as such that my recommendations may be inadequate or inappropriate. However I am trying both to understand and to help, so I shall venture forward.
When performing the following operations:
1.004*2
f[%, 3]
x = %/2
2.008
2.01
1.01
The result is as desired except in the output formatting; the underlying value of x is correct as can be seen with FullForm:
FullForm[x]
1.005`3.
Increasing its precision also results in all four digits being formatted in output:
SetPrecision[x, 4]
1.005
If this is not an acceptable method then perhaps setting a higher precision beforehand would be usable.
1.004*2
f[%, 3]
f[%, 4]
%/2
2.008
2.01
2.010
1.005
If this too is not acceptable then to the best of my knowledge Mathematica has no floating point format that is, as you seem to want a fundamentally different precision arithmetic than what is implemented in Mathematica.
Perhaps working with Rational values could work for you. As a rough and partial example:
SetAttributes[num, NHoldAll]
num /: num[x_] * (num[y_] | y_.) := num[x * y]
num /: num[x_] + (num[y_] | y_.) := num[x + y]
Format[num[x_]] := N[x]
g[num[x_] | x_, n_] := num @ Round[x, 10^(1 - n + ⌊Log10@Abs@x⌋)]
Now:
g[1.00412, 4] (* step to show that g may be used more than once *)
%*2
g[%, 3]
%/2
1.004
2.008
2.01
1.005
Related Q&A's:
Comments
Post a Comment