我想将64位数字从二进制转换为十进制。由于dec2bin
仅支持最多52位,因此我认为我可以使用uint64
来超越此限制:
function [dec] = my_bin2dec(bin)
v = uint64(length(bin)-1:-1:0);
base = uint64(2).^v;
dec = uint64(sum(uint64(base.*(uint64(bin-'0')))));
end
但是,它没有按预期工作:
my_bin2dec('111000000000000000000000000000000000001010110101011101000001110')
ans =
8070450532270651392
my_bin2dec('111000000000000000000000000000000000001010110101011101000001111')
ans =
8070450532270651392
这是正确的结果:
(111000000000000000000000000000000000001010110101011101000001110)bin
= (8070450532270651918)dec
(111000000000000000000000000000000000001010110101011101000001111)bin
= (8070450532270651919)dec
我错过了什么?好像还有一些操作仍然使用52位双算术执行,但我不知道哪一个。
我检查了uint64
的操作是否可用,而且我使用的操作(power
,times
,sum
)似乎在那里:
>> methods uint64
Methods for class uint64:
abs bitxor diff isinf mod plus sum
accumarray bsxfun display isnan mpower power times
all ceil eq issorted mrdivide prod transpose
and colon find ldivide mtimes rdivide tril
any conj fix le ne real triu
bitand ctranspose floor linsolve nnz rem uminus
bitcmp cummax full lt nonzeros reshape uplus
bitget cummin ge max not round xor
bitor cumprod gt min nzmax sign
bitset cumsum imag minus or sort
bitshift diag isfinite mldivide permute sortrowsc
答案 0 :(得分:4)
你说的是对的
似乎还有一些操作仍然使用52位双算法执行。
问题在于
dec = uint64(sum(uint64(base.*(uint64(bin-'0')))));
操作sum(uint64(base.*(uint64(bin-'0'))))
提供double
结果,其中只有大约15位有效数字。这就是你的最低位数错误的原因。后续转换为uint64
无济于事,因为精度已经丢失。
解决方案是在uint64
中对本地进行求和。这样可以得到uint64
结果的完整精度:
dec = sum(uint64(base.*(uint64(bin-'0'))), 'native');
答案 1 :(得分:1)
与@beaker有同样的想法,把它分成几块:
%% dec2bin
x=intmax('uint64')
MSBs = dec2bin( bitshift(x,-32) ,32)
LSBs = dec2bin( bitand(x, hex2dec('FFFFFFFF')) ,32)
y = [MSBs LSBs]
%% bin2dec
MSBs = y(1:32)
LSBs = y(33:64)
z = bitor( bitshift( uint64(bin2dec(MSBs)) , 32 ) , uint64(bin2dec(LSBs)) )
% (now x = z)
奇怪的是,似乎dec2bin
没有给出错误,但确实给出了64位数字的错误答案:
dec2bin( intmax('uint64') )
ans =
10000000000000000000000000000000000000000000000000000000000000000