Search code examples
matlabcomputation

To handle rational number without losing accuracy of computation in Matlab?


I want to use this rational number in computations without losing the accuracy of the picture in Matlab:

f = 359.0 + 16241/16250.0

I think storing, for instance by f = uint64(359.0 + 16241/16250.0) loses accuracy, seen as 360 in Matlab.

I think the best way to handle the thing is never to store the value but to store its factors like

% f = a + b/c
a = 359
b = 16241
c = 16250

and then doing computation by the variables a, b and c, and giving the result as a picture.

Is this a good way to maintain the accuracy?


Solution

  • As you suggest, if you absolutely don't want to lose accuracy when storing a rational number, the best solution probably is to store the number in terms of its integer components.

    Instead of your three components (f = a + b/c) you can reduce the reprentation to two components: f = n/d. Thus each rational number would be defined (and stored) as the two-component integer vector [n d]. For example, the number f in your example corresponds to n=5849991 and d=16250.

    To simplify handling rational numbers stored this way, you could define a helper function which converts from the [n d] representation to n/d before applyling the desired operation:

    useInteger = @(x, nd, fun) fun(x,double(nd(1))/double(nd(2)));
    

    Then

    >> x = sqrt(pi);
    >> nd = int64([5849991 16250]);
    >> useInteger(x, nd, @plus)
    ans =
      361.7719
    >> useInteger(x, nd, @times)
    ans =
      638.0824
    

    If you want to achieve arbitrarily high precision in computations, you should consider using variable-precision arithmetic (vpa) with string arguments. With that approach you get to specify how many digits you want:

    >> vpa('sqrt(pi)*5849991/16250', 50)
    ans =
    638.08240465923757600307902117159072301901656248436