Issue correlating exp() from fortran to matlab

5 views (last 30 days)
Maxwell
Maxwell on 13 Mar 2025
Edited: dpb on 18 Mar 2025
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 Comments
James Tursa
James Tursa on 15 Mar 2025
Edited: James Tursa on 15 Mar 2025
@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.

Sign in to comment.

Answers (0)

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!