我想在计算中使用这个有理数,而不会失去Matlab中图片的准确性:
f = 359.0 + 16241/16250.0
我认为存储,例如f = uint64(359.0 + 16241/16250.0)
会失去准确性,在Matlab中被视为360.
我认为处理这件事的最好办法是永远不要存储价值,而是存储像
这样的因素% f = a + b/c
a = 359
b = 16241
c = 16250
然后通过变量a,b和c进行计算,并将结果作为图片给出。
这是保持准确性的好方法吗?
答案 0 :(得分:6)
正如您所建议的,如果您在存储有理数时绝对不想失去准确性,那么最佳解决方案可能是将数字存储为整数分量。
您可以将代表减少为两个组件f = a + b/c
,而不是您的三个组件(f = n/d
)。因此,每个有理数将被定义(并存储)为双分量整数向量[n d]
。例如,示例中的数字f
对应n=5849991
和d=16250
。
为了简化以这种方式存储的有理数的处理,您可以定义一个辅助函数,在应用所需的操作之前将其从[n d]
表示转换为n/d
:
useInteger = @(x, nd, fun) fun(x,double(nd(1))/double(nd(2)));
然后
>> x = sqrt(pi);
>> nd = int64([5849991 16250]);
>> useInteger(x, nd, @plus)
ans =
361.7719
>> useInteger(x, nd, @times)
ans =
638.0824
如果要在计算中实现任意高精度,则应考虑将variable-precision arithmetic (vpa
)与字符串参数一起使用。使用这种方法,您可以指定所需的位数:
>> vpa('sqrt(pi)*5849991/16250', 50)
ans =
638.08240465923757600307902117159072301901656248436
答案 1 :(得分:6)
也许创建一个Rational
类并定义所需的操作(plus
,minus
,times
等。从这样的事情开始:
<强> Rational.m 强>
classdef Rational
properties
n;
d;
end
methods
function obj = Rational(n,d)
GCD = gcd(n,d);
obj.n = n./GCD;
obj.d = d./GCD;
end
function d = dec(obj)
d = double(obj.n)/double(obj.d);
end
% X .* Y
function R = times(X,Y)
chkxy(X,Y);
if isnumeric(X),
N = X .* Y.n; D = Y.d;
elseif isnumeric(Y),
N = X.n .* Y; D = X.d;
else
N = X.n .* Y.n; D = X.d .* Y.d;
end
R = Rational(N,D);
end
% X * Y
function R = mtimes(X,Y)
R = times(X,Y);
end
% X ./ Y
function R = rdivide(X,Y)
if isnumeric(Y),
y = Rational(1,Y);
else
y = Rational(Y.d,Y.n);
end
R = times(X,y);
end
% X / Y
function R = mrdivide(X,Y)
R = rdivide(X,Y);
end
% X + Y
function R = plus(X,Y)
chkxy(X,Y);
if isnumeric(X),
N = X.*Y.d + Y.n; D = Y.d;
elseif isnumeric(Y),
N = Y.*X.d + X.n; D = X.d;
else
D = lcm(X.d,Y.d);
N = sum([X.n Y.n].*(D./[X.d Y.d]));
end
R = Rational(N,D);
end
% X - Y
function R = minus(X,Y)
R = plus(X,-Y);
end
% -X
function R = uminus(X)
R = Rational(-X.n,X.d);
end
function chkxy(X,Y)
if (~isa(X, 'Rational') && ~isnumeric(X)) || ...
(~isa(Y, 'Rational') && ~isnumeric(Y)),
error('X and Y must be Rational or numeric.');
end
end
end
end
<强>实施例强>
构造对象:
>> clear all % reset class definition
>> r1 = Rational(int64(1),int64(2))
r1 =
Rational with properties:
n: 1
d: 2
>> r2 = Rational(int64(3),int64(4))
r2 =
Rational with properties:
n: 3
d: 4
加减:
>> r1+r2
ans =
Rational with properties:
n: 5
d: 4
>> r1-r2
ans =
Rational with properties:
n: -1
d: 4
乘以除:
>> r1*r2
ans =
Rational with properties:
n: 3
d: 8
>> r1/r2
ans =
Rational with properties:
n: 2
d: 3
获取小数值:
>> r12 = r1/r2; % 2/3 ((1/2)/(3/4))
>> f = r12.dec
f =
0.6667
答案 2 :(得分:0)
扩展到LuisMendo的答案
我将此作为你的建议的错误由py
>>> a = 638.08240465923757600307902117159072301901656248436059
>>> a
638.0824046592376 % do not know if Python is computing here with exact number
>>> b = 638.0824
>>> ave = abs(b+a)/2
>>> diff = abs(b-a)
>>> ave = abs(b+a)/2
>>> diff/ave
7.30193709165014e-09
这比上面提出的错误存储错误更多。
我在WolframAlpha中运行
x = sqrt(pi)
x*5849991/16250
并获取
509.11609919757198016211937362635174599076143654820109
我不确定这是否是您对答案的评论意思。
答案 3 :(得分:0)
扩展到chappjc的答案。
我现在
[B,T,F] = tfrwv(data1, 1:length(data1), length(data1)); % here F double
fs = Rational(uint64(5849991), uint64(16250));
t = 1/fs;
imagesc(T*t, F*fs, B);
我跑吧
Error using .*
Integers can only be combined with integers of
the same class, or scalar doubles.
Error in .* (line 23)
N = X .* Y.n; D = Y.d;
Error in * (line 34)
R = times(X,Y);
如何在这个班级中将双倍与Rational相乘?