Matlab dec2bin gives wrong values

I am using Matlab dec2bin to convert decimal to binary string. However, I am getting wrong results. For example:

>> dec2bin(13339262925365424727)

ans =

1011100100011110100101001111010011000111111100011011000000000000

      

I checked in both C ++ and wolfram alpha implementation and the correct result is:

1011100100011110100101001111010011000111111100011011001001010111

      

Is there a problem with my use of Matlab desc2bin?

Thank,

Gil.

+3


source to share


3 answers


Your code is equivalent to:

x=13339262925365424727;
dec2bin(x)

      

but if you check the value of x, you will notice that it is ahead of double precision. The number is just big to be stored in a 64-bit double. Accuracy 2 ^ 11, checkeps(x)

To deal with large numbers, using vpa

from symbolic toolkit is a good option, is that available?

Here is a solution using vpa:

function l=ldec2bin(x)
if x>2^52
    head=floor(x/2^52);
    tail=x-head*2^52;
    l=[ldec2bin(head),dec2bin(double(tail),52)];
else
    l=dec2bin(double(x));
end
end

      



using:

>> ldec2bin(vpa('13339262925365424727'))

ans =

1011100100011110100101001111010011000111111100011011001001010111

      

/ Update:

I came across a much shorter implementation dec2bin

for symbolic variables:

>> sdec2bin=@(x)(feval(symengine,'int2text',x,2))

sdec2bin = 

    @(x)(feval(symengine,'int2text',x,2))

>> sdec2bin(sym('13339262925365424727'))

ans =

1011100100011110100101001111010011000111111100011011001001010111

      

+8


source


Integer seems long, you might want to try the de2bi

function; http://www.mathworks.com/help/comm/ref/de2bi.html



+2


source


Assuming the input is smaller intmax('uint64')

as in the example, here is a solution that doesn't require the Symbolic Math toolbar. This supports two input arguments, matching dec2bin

is vectorized and should be much faster:

function s=int2bin(d,n)
%INT2BIN  Convert nonnegative integer to a binary string
if isempty(d)
    s = '';
    return;
end
d = d(:);
if ~isinteger(d) || any(d < 0)
    error('int2bin:InvalidIntegerInput',...
          'First input must be a nonnegative integer class array.');
end
if nargin < 2
    n = 1
else
    n = round(double(n));
end
m = double(nextpow2(max(d)));
s = [repmat('0',length(d),n-m) rem(bsxfun(@bitshift,d,1-m:0),2)+'0'];

      

If you don't mind performance and prefer a one-line anonymous function, try:

int2bin = @(d,n)char(rem(bsxfun(@bitshift,d(:),1-max(n,double(nextpow2(max(d(:))))):0),2)+'0');

      

or the one that uses bitand

instead bitshift

:

int2bin = @(d,n)char(~~bsxfun(@bitand,d(:),2.^(max(n,nextpow2(max(d(:)))):-1:0))+'0');

      

All versions above assume that d

an integer class is a non-negative variable , for example uint64(13339262925365424727)

, and that n

a non-negative numeric scalar is. You can find fully functional int2bin

and bin2int

functional on my GitHub .

+2


source







All Articles