我正在尝试将非常长的二进制字符串(通常大于52位)转换为数字。我不能有一个固定的超前窗口,因为我这样做是为了计算神经数据的Lempel-Ziv复杂度版本。
当我尝试转换任何长字符串时,bin2dec抛出并且错误,二进制字符串必须是52位或更少。
有没有办法绕过这个尺寸限制?
答案 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
将为Inf
或NaN
。所以你仍然需要找到存储结果数字的另一种方式。
这个算法的最终专业人员:您可以将pows2
缓存为大数字,然后将其中的一部分用于任何长度为N的新条带:
Nmax = 1e8; % already 700MB for pows2, watch out!
pows2 = 2.^(Nmax-1:-1:0);
然后使用
value = pows2(Nmax-N+1:end)*(strbin-'0')';
文件交换机上有一个名为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