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.
source to share
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
source to share
Integer seems long, you might want to try the de2bi
function;
http://www.mathworks.com/help/comm/ref/de2bi.html
source to share
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 .
source to share