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



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

当我尝试转换任何长字符串时,bin2dec会抛出一个错误,即二进制字符串必须小于等于52位。

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

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

或者更完整地描述你想要实现的目标。

编辑:

根据您的额外信息,我更确信转换为浮点不是您想要做的。如果您想将存储大小减少到更高效的大小,请转换为字节向量(uint8),它尽可能密集。只需使用整形将二进制字符串拆分为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位字。

您可以推出自己的实现:

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文件编译它。

由于@aardarkk而获得学分,但这里是他的算法的加速版本(速度快+-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:的任何新的strbin

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

最新更新