Skip to main content
4 of 6
bug fix
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k

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.5 and 1/2 when entered in Mathematica. But my request is to perform a very simple calculation: consider the number 1.004 and double it. The answer is 2.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 doing f to 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:

Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k