TransWikia.com

Can I change the default behavior so that "0.1" is interpreted as "1/10" automatically?

Mathematica Asked on March 12, 2021

Consider the function

f[a_] := NIntegrate[Sqrt[a + Log[x]], {x, 1, 10}, WorkingPrecision -> 30].

With this definition, I cannot call f[0.1] (for example) without Mathematica throwing an error, since "0.1" is interpreted automatically as a machine number with MachinePrecision (about 16), whereas the integration requires 30 digits of precision.

But when I enter 0.1, of course I really mean 1/10. One solution is to enter f[1/10], but this is very inconvenient to do every time, especially because my real functions involve many parameters with long strings of decimal numbers. What’s the best way around this issue? Ideally, I’d like Mathematica to interpret 0.1 as 1/10 automatically, as mentioned in the title.

EDIT

To clarify, I would like any decimal number input be treated as the exact mathematical number with the same name. For example, 0.### should become ###/1000. As pointed out in the comments, Rationalize converts 0.33333333 to 1/3, which I would consider a problem for my case. I would like Mathematica to treat decimal number input as exact numbers without rounding to any finite precision, nor assuming that I intended a "close" but different rational number.


Another option would be to change the function definition:

f[a_] := NIntegrate[Sqrt[Rationalize[a] + Log[x]], {x, 1, 10}, WorkingPrecision -> 30]

or

f[a_] := NIntegrate[Sqrt[SetPrecision[a, [Infinity]] + Log[x]], {x, 1, 10}, WorkingPrecision -> 30]

But this too would be quite inconvenient to do for every function I use. I also worry about the fact that SetPrecision[0.1, [Infinity]] does not give 1/10. So all this makes me wonder what the "right" method is.

4 Answers

Clear["Global`*"]

Since f makes use of a numeric technique, the argument a should be restricted to being numeric. Set the precision of a to at least the WorkingPrecision used in NIntegrate.

f[a_?NumericQ, wp : _Integer : 30] := Module[{ap = SetPrecision[a, 
  Max[wp, Precision[a]]]},
  NIntegrate[Sqrt[ap + Log[x]], {x, 1, 10}, WorkingPrecision -> wp]]

f[1/10]

(* 11.3397714471112499234083518037 *)

f[0.1]

(* 11.3397714471112499447483664367 *)

f[0.1, 20]

(* 11.339771447111249944 *)

Answered by Bob Hanlon on March 12, 2021

Exact conversion to the underlying IEEE-754 machine-precision number can be done with SetPrecision[x,∞]:

x = 1/3 // N
(*    0.333333    *)

SetPrecision[x, ∞]
(*    6004799503160661/18014398509481984    *)

So you see that $1/3$ is represented internally as $6,004,799,503,160,661times2^{-54}$.

Answered by Roman on March 12, 2021

Here's a $PreRead approach:

$PreRead = # /. 
    s_String /; StringMatchQ[s, NumberString] :> 
     With[{pos = StringPosition[s, "."]},
      RowBox[{StringDrop[s, First[pos]], "/", 
         10^(StringLength[s] - pos[[1, 1]])}]
       /; Length[pos] === 1] &;

(* new Input cell *)
0.231 + 27 Exp[10.856 x]
(*  231/1000 + 27 E^(1357 x/125)  *)
(* new Input cell *)
$PreRead =.    (* reset *)

%% // N
(*  0.231 + 27. 2.71828^(10.856 x)  *)

Gratuitous remark: I never use $PreRead (anymore). I think the way it can mess with the input is a potential headache and, in this case, I'd rather put up with the inconvenience of typing 10856/1000.

Answered by Michael E2 on March 12, 2021

This will do what you're after:

rd = With[{t = RealDigits[#][[1]]},,FromDigits[t]/10^Length@t] &;

E.g.:

rd[0.12345675785894491727276262524416723451]

12345675785894491727276262524416723451/100000000000000000000000000000000000000

Compare:

Rationalize[0.12345675785894491727276262524416723451, 0]

2986272931814910240/24188817069267814669

Specifying precision as part of the input can address this:

Rationalize[0.12345675785894491727276262524416723451`100, 0]

12345675785894491727276262524416723451/100000000000000000000000000000000000000

I suppose a simple wrapper could be used to automate the conversion when calling your functions.

Answered by ciao on March 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP