2

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

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

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

4

3 回答 3

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 位字。

于 2012-09-10T14:58:31.843 回答
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 位,也会出现问题。此时,您需要可变精度算术来跟踪它。并将其添加到计算中确实减慢了速度。.mex如果我是你,如果你需要 MATLAB 中的功能,我会强烈考虑从文件中编译它。

于 2012-09-10T16:08:51.207 回答
1

归功于@aardvarkk,但这是他算法的加速版本(+- 100x 快):

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将是Infor NaN。所以你仍然需要找到另一种存储结果数字的方法。

该算法的最后一个专家:您可以缓存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数值上界的解法

File Exchange 上有一个名为 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
于 2012-09-10T17:26:17.123 回答