在Matlab中将大于52位的二进制字符串转换为单个字符串?

时间:2012-09-10 14:49:53

标签: matlab numerical-methods

我正在尝试将非常长的二进制字符串(通常大于52位)转换为数字。我不能有一个固定的超前窗口,因为我这样做是为了计算神经数据的Lempel-Ziv复杂度版本。

当我尝试转换任何长字符串时,bin2dec抛出并且错误,二进制字符串必须是52位或更少。

有没有办法绕过这个尺寸限制?

3 个答案:

答案 0 :(得分:2)

dec2bin抛出该错误,因为单个版本无法存储那么多精度。你的问题是不可能的。您有两种选择:将值存储在浮点值以外的值中,或者在转换之前抛弃一些精度。

或者更完整地描述你想要完成的事情。

编辑:

根据您的其他信息,我更确定转换为浮点数不是您想要做的。如果您希望将存储大小减小到更高效的位置,请转换为字节向量(uint8),这是您可以获得的密集度。只需使用reshape将二进制字符串分成N行,每行8位。这似乎是一种可接受的生物数据方法。

str = char((rand(1, 100)>0.5) + '0');    % test data
data = uint8(bin2dec(reshape(str(1:end-mod(end,8)), [], 8)));

在这段代码中,我将任何不均匀划分为8的位抛出。或者,跳过uint8步骤,只对生成的向量执行处理,其中每个双精度浮点数代表一个8位字。序列

答案 1 :(得分:2)

你可以推出自己的实现:

len = 60;

string = [];
for i = 1:len
  string = [string sprintf('%d', randi([0 1]))];
end

% error
% bin2dec(string);

% roll your own...
value = 0;
for i = length(string):-1:1
  value = value + str2num(string(i))*2^(length(string)-i);
end

我只是循环遍历字符串并添加一些值。最后,value将包含字符串的十进制值。这对你有用吗?

注意:此解决方案。您可以通过预先分配我在自己的机器上执行的字符串来加快速度。此外,如果您的号码达到1e6位,它将会出现问题。此时,您需要使用变量精度算法来跟踪它。并将其添加到计算真的减慢了速度。如果我是你,如果你需要MATLAB中的功能,我强烈考虑从.mex文件中编译它。

答案 2 :(得分:1)

由于@aardvarkk的积分,但这是他的算法的加速版本(+ - 快100倍):

N=100;
strbin = char(randi(2,1,N)+'0'-1);

pows2 = 2.^(N-1:-1:0);
value=pows2*(strbin-'0')';

double的范围最多只有1.79769e+308 2^1024给予或接受。从那时起,value将为InfNaN。所以你仍然需要找到存储结果数字的另一种方式。

这个算法的最终专业人员:您可以将pows2缓存为大数字,然后将其中的一部分用于任何长度为N的新条带:

Nmax = 1e8; % already 700MB for pows2, watch out!
pows2 = 2.^(Nmax-1:-1:0);

然后使用

value = pows2(Nmax-N+1:end)*(strbin-'0')';

matlab数字上限

的解决方案

文件交换机上有一个名为vpi的工具:http://www.mathworks.com/matlabcentral/fileexchange/22725

它允许你使用非常大的整数(2^5000?没有概率)。它在计算所有内容时速度较慢(很多),我建议不要使用上面的方法。但是,嘿,你不能拥有一切!

下载软件包addpath,以下内容可能有效:

N=3000;
strbin = char(randi(2,1,N)+'0'-1);

binvals=strbin-'0';
val=0;
twopow=vpi(1);
for ii=1:N
    val=val+twopow*binvals(N-ii+1);
    twopow=twopow*2;
end