matlab代码中的基本转换错误

eal*_*iaj 5 math matlab

我创建了以下简单的matlab函数,将数字从任意基数转换为十进制数

这是第一个

function decNum = base2decimal(vec, base)

decNum = vec(1);
for d = 1:1:length(vec)-1
    decNum = decNum*base + vec(d+1);     
end 
Run Code Online (Sandbox Code Playgroud)

这是另一个

function baseNum = decimal2base(num, base, Vlen)
ii = 1;
if num == 0
    baseNum = 0;
end
while num ~= 0 
    baseNum(ii) = mod(num, base);
    num = floor(num./base);
    ii = ii+1;
end
baseNum = fliplr(baseNum);

if Vlen>(length(baseNum))
    baseNum = [zeros(1,(Vlen)-(length(baseNum))) baseNum ];
end
Run Code Online (Sandbox Code Playgroud)

由于这些函数无法成功转换多大的数量有多大的限制,但在测试它们时我注意到以下错误

我们使用以下测试功能

num = 201;

pCount = 7
x=base2decimal(repmat(num-1, 1, pCount), num)
repmat(num-1, 1, pCount)
y=decimal2base(x, num, 1)
isequal(repmat(num-1, 1, pCount),y) 
Run Code Online (Sandbox Code Playgroud)

base201中具有七(7)位数的假定向量工作正常,但是与base200相同的向量不会返回预期结果,即使它更小并且理论上应该成功转换.

小智 1

(一个初步评论:调用base2decimal不会产生十进制数,而是产生一个数字:-D)

这是由于浮点精度有限(在我们的例子中为double)。要测试它,只需在 MATLAB 命令行窗口中键入:

>> 200^7 - 1 == 200^7

ans = 

     1

>> mod(200^7 - 1, 200)

ans =

     0
Run Code Online (Sandbox Code Playgroud)

这意味着以 200 为基数的数字值(恰好是 200 7 −1)精确地表示为 200 7,并且表示的“真实”值是 200 7

另一方面:

>> 201^7 - 1 == 201^7

ans =

 1
Run Code Online (Sandbox Code Playgroud)

所以这两个数字仍然表示相同,但​​是

>> mod(201^7 - 1, 201)

ans =

   200
Run Code Online (Sandbox Code Playgroud)

这意味着这两个值共享 201 7 −1 的“真实”表示,这恰好是您所期望的值。

长话短说

当存储在 a 中时double,200 7 -1 不准确地表示为 200 7,而 201 7 -1 则准确表示。

“较大的数字比较小的数字表示得更不准确”是一种误解:如果这是真的,那么就不会有可以精确表示的大数字了。