【问题标题】:Matlab dec2bin gives wrong valuesMatlab dec2bin 给出错误的值
【发布时间】:2014-08-15 18:10:26
【问题描述】:

我正在使用 Matlab 的 dec2bin 将十进制数转换为二进制字符串。但是,我得到了错误的结果。例如:

>> dec2bin(13339262925365424727)

ans =

1011100100011110100101001111010011000111111100011011000000000000

我检查了 C++ 实现和 wolfram alpha,正确的结果是:

1011100100011110100101001111010011000111111100011011001001010111

我使用Matlab的desc2bin有什么问题吗?

谢谢,

吉尔。

【问题讨论】:

标签: matlab


【解决方案1】:

您的代码相当于:

x=13339262925365424727;
dec2bin(x)

但是如果你检查 x 的值,你会发现它超过了双精度。这个数字太大了,无法存储在 64 位双精度中。精度为2^11,查看eps(x)

要处理大量数字,使用符号工具箱中的vpa 是一个不错的选择,是否可用?

这是一个使用 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

用法:

>> ldec2bin(vpa('13339262925365424727'))

ans =

1011100100011110100101001111010011000111111100011011001001010111

/更新:

我遇到了一个更短的 dec2bin 符号变量实现:

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

sdec2bin = 

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

>> sdec2bin(sym('13339262925365424727'))

ans =

1011100100011110100101001111010011000111111100011011001001010111

【讨论】:

  • 感谢您的帮助!
【解决方案2】:

整数似乎很长,也许你应该尝试de2bi函数; http://www.mathworks.com/help/comm/ref/de2bi.html

【讨论】:

  • 感谢您的帮助!
  • 这并不能解决问题。 fliplr(char(de2bi(13339262925365424727)+48))dec2bin(13339262925365424727) 相同。 de2bi 的文档没有提到它,它似乎也是使用双精度实现的,因此对于大于 flintmax 的值可能返回不准确的输出。
【解决方案3】:

假设输入小于intmax('uint64'),如示例所示,这是一个不需要符号数学工具箱的解决方案。这支持两个输入参数,匹配dec2bin,是矢量化的,应该更快:

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'];

如果您不介意性能降低一点并且更喜欢单行匿名函数,请尝试:

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

或者这个使用bitand而不是bitshift

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

以上所有版本都假定d 是一个非负的integer class 变量,例如uint64(13339262925365424727),而n 是一个非负的数值标量。您可以找到功能齐全的int2binbin2int 函数on my GitHub

【讨论】:

  • 感谢您的帮助 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多