# Working precision becomes different

Hi I'm working on some numerical integration that needs to be evaluated up to a certain number of digits, however, I encounter the following problem:

If I use,

N[2/5, 10]


the output becomes

0.410.


but if I use

N[2./5, 10]


the output becomes

0.4


I want my results to give up to 10 digits (first example) and at the same time I want to use machine float numbers (second example) so that the numerical evaluation is fast. Is there a way to fix this?

Thanks!

• Precision[2./5] will always be MachinePrecision$\approx 15.9546$, so your N[] won't do anything else to it. 0.410. is an arbitrary-precision number, like it or not. Nov 3, 2017 at 7:24
• But I used N[2./5, 10]. Shouldn't it work since 10 is still less than the Machine precision? Nov 3, 2017 at 7:27
• No, the 2. there doomed the conversion to begin with. You start with a machine precision number, you (almost always) end up with a machine precision number. "I want my results to give up to 10 digits (first example) and at the same time I want to use machine float numbers (second example) so that the numerical evaluation is fast." is a "wanting to eat and have your cake" case. Nov 3, 2017 at 7:29
• Oh ok. So basically what I want to do is impossible lol. Thanks! Nov 3, 2017 at 7:31
• Not impossible (hence "almost always"); evaluate SetPrecision[0.4, 10] for instance. But, even if you only have 10 digits in place, you are still using arbitrary-precision arithmetic and not machine precision arithmetic. Nov 3, 2017 at 7:32

There are two kinds of inexact numbers in Mathematica:

Machine numbers are directly supported by your CPU (hence the name), so they are extremely fast to work with. However, they do no include precision tracking.

Arithmetic for arbitrary precision numbers is implemented in software, and it is much slower. But arbitrary precision numbers use precision tracking and can have any number of digits.

These types of numbers are "sticky" like this:

• arithmetic between exact and arbitrary precision numbers results in an arbitrary precision number

• arithmetic between machine numbers and anything else results in machine numbers

2. is a machine number, therefore all numerical operations (including N) done with it result in a machine number.

To convert between these various types of numbers, you can use SetPrecision.

SetPrecision[2.5, 10] (* machine number -> arbitrary precision *)
(* 2.500000000 *)

SetPrecision[2.5, Infinity] (* machine number -> exact *)
(* 5/2 *)


I want my results to give up to 10 digits (first example) and at the same time I want to use machine float numbers (second example) so that the numerical evaluation is fast. Is there a way to fix this?

Not really. All you can do is truncate the final result to 10 digits. You cannot force machine arithmetic to use 10 digits instead of ~16. It is implemented in hardware and it cannot be changed.

If you want to see what happens when you calculate with exactly 10 digits, use the ComputerArithmetic package. It is designed exactly for such exploration. However, it is much slower than even the built-in arbitrary precision arithmetic.

Note that in Mathematica it isn't really possible to do 10-digit arithmetic even with arbitrary precision numbers. Mathematica will track the precision, thus the result you get after operating together two 10-digit numbers won't be exactly 10-digit.

1.1210 - 1.110
(* 0.020000000 *)

Precision[%]
(* 7.95468 *)


Update: Carl Woll points out that this above is not correct.

It is possible to emulate fixed precision with arbitrary precision numbers by blocking $MinPrecision and $MaxPrecision: Block[{$MinPrecision=10,$MaxPrecision=10},0.110-0.0110]

• It is possible to emulate fixed precision with arbitrary precision numbers by blocking $MinPrecision and $MaxPrecision: Block[{$MinPrecision=10,$MaxPrecision=10},0.110-0.0110] Nov 3, 2017 at 14:04