Issue correlating exp() from fortran to matlab

5 ビュー (過去 30 日間)
Maxwell
Maxwell 2025 年 3 月 13 日
編集済み: dpb 2025 年 3 月 18 日
Important clarification - I need Matab to match Fortran. I cannot change the Fortran code. I am working in 2018b and the function I am having an issue with is gz = 1.0 / (1+0.0247*exp(0.650*log(0.1089*re))). re is single precision in this case (Fortran). I was able to correlate 0.650*log(0.1089*re) so I know that the issue is with exp. In fortran, exp(0.650*log(0.1089*re)) = 24.09045, (24.0904521942139 if double precision), but in Matlab it is 24.0904541, (24.090454101562500 double precision). How can I modifiy the code to be the same as fortran. I have tried double() and single() everywhere but it didn't work.
The weirdest part: This code is part of a function that is used >500 times. I would say 350/500 times the results match up, but there are random stretches where it is off as described above. There is also a near similar function gx (some of the constants are different) that works 100% of the time. I made sure that I used single() and double() in the same exact spots but still got this issue.
  13 件のコメント
James Tursa
James Tursa 2025 年 3 月 15 日
編集済み: James Tursa 2025 年 3 月 15 日
@Walter Roberson And that leaves a bit of wiggle room in the result. E.g.,
p = randi([-5,5],10,10);
x = sum(2.^p); % some random values that can be represented exactly in double and vpa
X = string(x');
IEEE_hex = string(num2hex(x));
table(X,IEEE_hex) % demonstrate that these are "nice" in binary floating point format
ans = 10x2 table
X IEEE_hex __________ __________________ "120.3125" "405e140000000000" "10.875" "4025c00000000000" "26.34375" "403a580000000000" "34.03125" "4041040000000000" "108.125" "405b080000000000" "56.28125" "404c240000000000" "28.8125" "403cd00000000000" "23.03125" "4037080000000000" "37.25" "4042a00000000000" "31.25" "403f400000000000"
digits 50
double(exp(vpa(x))) - exp(x)
ans = 1×10
1.0e-03 * 0 0 0 0 0 0 -0.4883 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
It wasn't too hard to find a value x for which exp(x) did not give a result that was correctly rounded "as if the calculation were performed in infinite precision". This is unlike the IEEE requirement for the +, -, *, and / operations which do have this strict requirement.
exp_vpa_x = string(num2hex(double(exp(vpa(x)))));
exp_x = string(num2hex(exp(x)));
table(exp_vpa_x,exp_x)
ans = 10x2 table
exp_vpa_x exp_x __________________ __________________ "4ac7d28912b900dc" "4ac7d28912b900dc" "40e9ccd7d3d55bc5" "40e9ccd7d3d55bc5" "42501110262b98ea" "42501110262b98ea" "43011c005aae8303" "43011c005aae8303" "49afcf51cc64d9fe" "49afcf51cc64d9fe" "4502564116ff8878" "4502564116ff8878" "4287b6b72fba0d83" "4287b6b72fba0d84" "4202ba2f9c4855b1" "4202ba2f9c4855b1" "434abae41f425f94" "434abae41f425f94" "42c0f63a92073371" "42c0f63a92073371"
The 7th value above differs by 1 ULP. A different library using a different algorithm meeting the same 1 ULP standard as MATLAB could get a different result. Hence the advice to not rely on exact comparisons for library functions.
dpb
dpb 2025 年 3 月 15 日
+1 @James Tursa for elegant exposition...

サインインしてコメントする。

回答 (0 件)

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

製品


リリース

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by