当前位置: 首页 > 知识库问答 >
问题:

如何阻止MATLAB从舍入极小的值到0?

越胤
2023-03-14

我在MATLAB中有一个代码,它可以处理非常小的数字,例如,我有10^{-25}量级的值,但是当MATLAB进行计算时,值本身被舍入为0。注意,我指的不是格式来显示这些额外的小数,而是数字本身被更改为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:

这是我的数据文件,用于代码。运行代码后(大约需要一分钟半的时间来完成运行),变量x中的第11行显示0(即使双击检查其真实值),而该行不应该显示0。


共有1个答案

汤弘文
2023-03-14

你遇到的问题是因为浮点的IEEE标准不能区分你的数字和零,因为它们没有利用足够的比特。

看看John D'Errico的大十进制类和变精度整数算法。另一个选择是使用Java的大整数类,但是如果你不熟悉在MATLAB中使用Java和其他rex的库,这可能会更具挑战性。

你能举一个使用1e-25得到零的计算例子吗?下面是一个名为small\u num的浮点和John的一个名为small\u 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
 类似资料:
  • 我将货币值作为浮动存储在mysql表中。 问题是,mysql正在向上或向下舍入数字。 例如,12345.68四舍五入为12345.7 如何停止此操作,或者是否应该使用更好的数据类型? 我希望将原始值保留在小数点后2位以内。

  • 问题内容: 我需要将PHP中的小数点四舍五入到小数点后两位,以便: 变成… 我已经尝试过 number_format ,但这只是将值 舍 入到 49.96 。我不能使用 substr, 因为该数字可能较小(例如7.950)。到目前为止,我一直无法找到答案。 任何帮助,不胜感激。 问题答案: 这可以工作:

  • 问题内容: 我想将双精度值四舍五入到2个小数点。 例如:我有双d = 2;结果应为result = 2.00 问题答案: 内部表示形式在2和2.00之间没有差异。您可以使用四舍五入的值到最接近的整数- 使该轮为2位小数,你可以乘100,圆形,再除以100,但你不应该期望的结果是 准确 2DPS,由于二进制浮点运算的性质。 如果您只想将值 格式化 为两位小数,请查看-如果您对 计算中 的小数位数感兴

  • 我试图显示从序列号接收到的值,但Matlab不接受十进制数结果。我想从一个设备接收A=0.123,值乘以1000,然后通过串行发送到matlab。 matlab脚本接收123,但当该数字被除以以获得原始值时,matlab显示0。 哪个返回 我认为问题在于typecast(X,type)函数 将X中的数值转换为类型指定的数据类型。 我把它改成: 但一切都没有改变。我试过这个问题和这里的建议,但都不管

  • 我需要将PHP中的一个小数点舍入为两位小数,以便: 变成。。。 我尝试了数字_格式,但这只是将值舍入到49.96。我不能使用substr,因为数字可能更小(如7.950)。到目前为止,我还没有找到这个问题的答案。 非常感谢您的帮助。

  • 问题内容: 如何将matchpercent的结果四舍五入到小数点后两位(%)?我正在使用以下方法返回一些结果: 问题答案: 转换/转换结果: …这里的数字足够大,不能截断小数点左边。也就是说,如果使用“ 123.456”,则由于总长度为7位,因此需要使用DECIMAL(7,2)。