使用uint64将64位数字从二进制转换为十进制

时间:2015-09-01 14:52:28

标签: matlab

我想将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的操作是否可用,而且我使用的操作(powertimessum)似乎在那里:

>> 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   

2 个答案:

答案 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