我在MATLAB中有一个代码,它使用非常小的数字,例如,我的值大约为10 ^ { - 25},但是当MATLAB进行计算时,值本身会舍入为0。注意,我不是指format
来显示这些额外的小数,而是将数字本身更改为0.我认为原因是因为默认情况下,MATLAB在小数点后使用最多15位数字计算。如何更改此值,以便保留非常小的数字,因为它们在计算中?
编辑:
我的代码如下:
clc;
clear;
format long;
% Import data
P = xlsread('Data.xlsx', 'P');
d = xlsread('Data.xlsx', 'd');
CM = xlsread('Data.xlsx', 'Cov');
Original_PD = P; %Store original PD
LM_rows = size(P,1)+1; %Expected LM rows
LM_columns = size(P,2); %Expected LM columns
LM_FINAL = zeros(LM_rows,LM_columns); %Dimensions of LM_FINAL
for ii = 1:size(P,2)
P = Original_PD(:,ii);
% c1, c2, ..., cn, c0, f
interval = cell(size(P,1)+2,1);
for i = 1:size(P,1)
interval{i,1} = NaN(size(P,1),2);
interval{i,1}(:,1) = -Inf;
interval{i,1}(:,2) = d;
interval{i,1}(i,1) = d(i,1);
interval{i,1}(i,2) = Inf;
end
interval{i+1,1} = [-Inf*ones(size(P,1),1) d];
interval{i+2,1} = [d Inf*ones(size(P,1),1)];
c = NaN(size(interval,1),1);
for i = 1:size(c,1)
c(i,1) = mvncdf(interval{i,1}(:,1),interval{i,1}(:,2),0,CM);
end
c0 = c(size(P,1)+1,1);
f = c(size(P,1)+2,1);
c = c(1:size(P,1),:);
b0 = exp(1);
b = exp(1)*P;
syms x;
eqn = f*x;
for i = 1:size(P,1)
eqn = eqn*(c0/c(i,1)*x + (b(i,1)-b0)/c(i,1));
end
eqn = c0*x^(size(P,1)+1) + eqn - b0*x^size(P,1);
x0 = solve(eqn);
x0 = double(x0);
for i = 1:size(x0)
id(i,1) = isreal(x0(i,1));
end
x0 = x0(id,:);
x0 = x0(x0 > 0,:);
clear x;
for i = 1:size(P,1)
x(i,:) = (b(i,1) - b0)./(c(i,1)*x0) + c0/c(i,1);
end
% x = [x0 x1 ... xn]
x = [x0'; x];
x = x(:,sum(x <= 0,1) == 0);
% lamda
lamda = -log(x);
LM_FINAL(:,ii) = lamda;
end
问题在于此步骤:
for i = 1:size(P,1)
x(i,:) = (b(i,1) - b0)./(c(i,1)*x0) + c0/c(i,1);
end
“差异”非常接近0.如何在此步骤中停止此舍入?
例如,当i = 10时,我有以下值:
b_10 = 0.006639735483297
b_0 = 2.71828182845904
c_10 = 0.000190641848119641
c_0 = 0.356210110252579
x_0 = 7.61247930625269
在进行计算之后,我们得到:-1868.47805854794 + 1868.47805854794,它产生-2.27373675443232E-12的差异,由MATLAB舍入为0。
编辑2:
Here是我的数据文件,用于代码。运行代码后(大约需要一分半钟才能完成运行),变量11
中的行x
显示0(即使双击后检查它的实际值),当它应该'吨。
答案 0 :(得分:5)
您遇到的问题是因为IEEE standard for floating points无法将您的数字与零区分开来,因为它们没有使用足够的位数。
看看John D'Errico的Big Decimal Class和Variable Precision Integer Arithmetic。另一种选择是使用Big Integer Class from Java,但如果您不熟悉使用Java and othe rexternal libraries in MATLAB,那可能会更具挑战性。
您能举例说明您使用1e-25并获得零的计算吗?这是我得到的一个名为small_num
的浮点和John的高精度浮点数之一,在分配它们并乘以small_hpf
时称为pi
。
>> small_num = 1e-25
small_num =
1.0000e-25
>> small_hpf = hpf(1e-25)
small_hpf =
1.000000000000000038494869749191839081371989361591338301396127644e-25
>> small_num * pi
ans =
3.1416e-25
>> small_hpf * pi
ans =
3.141592653589793236933163473501228686498684350685747717239459106e-25