Skip to main content

numerics - A problem about function N


Toady,I have a problem about N,described as below:



For example


 N[1/3, 5]
(* ==> 0.33333*)

and N[1/3, 5] can make the result keep five significant figures.


data= RandomReal[{0, 2},8]
(* ==> {0.952811, 0.834171, 0.309447, 1.41046, 1.46811, 0.385663,1.50229,1.82034}*)

However,I want to make the data Keep four significant figures,so I use the function N[#, 4]&


N[#, 4]&/@data

(* ==> {0.952811, 0.834171, 0.309447, 1.41046, 1.46811, 0.385663,1.50229,1.82034}*)

Unfortunately,it failed.


My trail:


I copy the result,and paste in a input:


0.9528112485377731`, 0.8341711402854446`, 0.3094468949977962`, 
1.410457480346131`, 1.4681075372399688`, 0.38566305213741137`,
1.502289805503937`, 1.820341132427437`

I wipe out the symbol `,and



data1= {0.9528112485377731, 0.8341711402854446, 0.3094468949977962, 
1.410457480346131, 1.4681075372399688, 0.38566305213741137,
1.502289805503937, 1.820341132427437};
N[#, 4]&/@data1

==>(Wrong result,still keeping six significant figures )


{0.952811, 0.834171, 0.309447, 1.41046, 1.46811, 0.385663, 1.50229, 1.82034}

So my question is why and how to revise it?



Answer




Arbitrary and machine precision


It is important to understand that there are two different and in some respects separate numeric systems within Mathematica: machine-precision and arbitrary-precision. (I described this in brief here.)


Machine-precision numerics are much faster than arbitrary precision numerics, therefore it is normally undesirable to convert machine to arbitrary as you gain no precision and lose much performance. N respects this situation by not converting machine-precision numbers into arbitrary-precision numbers:


x = 1.23456789
Precision[x]


1.23457

MachinePrecision


y = N[x, 3]
Precision[y]


1.23457

MachinePrecision

Although this example is attempting to truncate a MachinePrecision number the corollary to this is that N also will not raise the precision of such as number. See: Confused by (apparent) inconsistent precision



The solution is not to use N for this operation. The correct tool will depend on your task.


Formatting


If this is to be a formatting operation use a formatting tool such as NumberForm:


NumberForm[data1, 4]


{0.9528, 0.8342, 0.3094, 1.41, 1.468, 0.3857, 1.502, 1.82}

There are multiple options and several related functions which should allow you to format your output quite precisely. See the documentation for more.


Converting to arbitrary precision



If you wish to convert machine-precision to arbitrary-precision use e.g. SetAccuracy or SetPrecision:


data2 = SetPrecision[data1, 4]


{0.9528, 0.8342, 0.3094, 1.410, 1.468, 0.3857, 1.502, 1.820}

Precision /@ data2


{4., 4., 4., 4., 4., 4., 4., 4.}


Note that although these numbers have less precision than machine precision they are still arbitrary precision numbers, and will incur the additional overhead of that system along with precision tracking etc.


Rounding a machine-precision number


Perhaps the most likely desire is the one I overlooked initially, as noted in the comments and further discussed in How do you round numbers so that it affects computation? you can indeed Round a machine-precision number to approximate fewer digits, but be aware that you are truncating (zero-filling) binary digits therefore things may not work exactly as you expect. For example:


data3 = Round[data1, 0.001]


{0.953, 0.834, 0.309, 1.41, 1.468, 0.386, 1.502, 1.82}

data3 // InputForm



{0.9530000000000001, 0.834, 0.309, 1.41, 1.468, 0.386, 1.502, 1.82}

Note the first element.


Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...