计算精度 [英] Precision of calculations

查看:95
本文介绍了计算精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Fortran中对一个双精度变量进行计算,计算后该变量的值变为-7.217301636365630e-24.

I am doing a calculation in Fortran on a double-precision variable, and after the calculation the variable gets the value -7.217301636365630e-24.

但是,当我在Matlab中进行相同的计算时,变量仅获得值0.有没有一种方法可以提高MatLAB的计算精度,使我也能够得到7e-24的数量?

However, when I do the same computation in Matlab, the variable just gets the value 0. Is there a way to increase the precision of MatLAB when doing calculations such that I would also be able to get something on the order of 7e-24?

理想情况下,这可以应用于脚本中的所有计算,而不仅仅是单个变量.与使用format long时类似.

Ideally, it would be something I could apply to all calculations in the script and not just a single variable. Something similar to when using format long.

对我来说,这种精确度至关重要,因为我需要确定变量是否确实为负数.

For me this kind of precision is crucial as I need to determine if a variable is indeed negative or not.

我已经添加了代码.它很长,但是我不能不把变量及其精度丢掉而无法进一步修整.最后一个术语Ax(i,:,:)是我希望具有非常高的精度的术语.所以重要的东西只出现在最后一行.

I have added the code. It is rather long, but I couldn't trim it further without throwing away variables and their precision. The last term, Ax(i,:,:), is the one that I would like to have a very high precision on. So the important stuff occurs only in the last line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CONSTANTS
clc
clear all

sym_weight     = [4/9, 1/9,1/9,1/9,1/9, 1/36,1/36,1/36,1/36];


dir_x  = [  0,   1,  0, -1,  0,    1,  -1,  -1,   1];
dir_y  = [  0,   0,  1,  0, -1,    1,   1,  -1,  -1];



ly = 11; lx = ly;
xC = 5; yC=xC;    

density_high = 1.0;
density_low = 0.1;
radius  = 2;
interface_w = 1;
sigma_st = 0.0001;


beta  = 12*sigma_st/(interface_w*(density_high-density_low)^4);
kappa = 1.5*sigma_st*interface_w/(density_high-density_low)^2;





saturated_density = 0.5*(density_high+density_low);
for x=1:lx
    for y=1:ly
        for i=1:9
            fIn(i, x, y) = sym_weight(i)*density_high;
            gIn(i, x, y) = 3*sym_weight(i);

            test_radius = sqrt((x-xC)^2 + (y-yC)^2);
            if(test_radius <= (radius+interface_w))
                fIn(i, x, y) = sym_weight(i)*( saturated_density - 0.5*(density_high-density_low)*tanh(2*(radius-sqrt((x-xC)^2 + (y-yC)^2))/interface_w) );
            end
        end
    end
end




density_2d = ones(lx)*saturated_density;
for i=1:lx
    density_aux(:,:,i) = abs(density_2d(:, i)');
end



density_local             = sum(fIn);
L_density_local           = (+1.0*(circshift(density_local(1,:,:), [0, +1, +1]) + circshift(density_local(1,:,:), [0, -1, +1]) + circshift(density_local(1,:,:), [0, +1, -1]) + circshift(density_local(1,:,:), [0, -1, -1])) + ...
                             +4.0*(circshift(density_local(1,:,:), [0, +1, +0]) + circshift(density_local(1,:,:), [0, -1, +0]) + circshift(density_local(1,:,:), [0, +0, +1]) + circshift(density_local(1,:,:), [0, +0, -1])) + ...
                             -20.0*density_local(1,:,:));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




chem_pot   = 4*beta*(density_local-density_low).*(density_local-density_high).*(density_local-density_aux) - kappa*L_density_local/6;






for i=3
    Ax(i,:,:)            =     (+circshift(chem_pot(1,:,:), [0,-2*dir_x(i),-2*dir_y(i)]) -             chem_pot(1,:,:));                                          
end 

推荐答案

您尚未显示fortran代码,但是请注意,在Fortran中,您可以这样做:

You have not shown the fortran code, but be aware that in Fortran, when you do this:

 density_low = 0.1

文字0.1是单精度的,而与density_low的类型无关. 所有这些文字都必须用0.1D00.1_k表示,其中k是适当的种类整数.

The literal 0.1 is single precision, regardless of the type of density_low. All of those literals need to be expressed as 0.1D0 or 0.1_k where k is the appropriate kind integer.

(很抱歉,您知道吗,但这是一个常见错误)

(Sorry if you knew that, but its a common mistake )

这篇关于计算精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆