Fortran converts mixed precision expressions according to well defined rules that have been in place for decades. Perhaps it would help with your understanding to write out the long form of the mixed-precision expression.
print *, "single * single: x * x = ", x*x ! 1.51289999
print *, "double * double: xx * xx = ", xx*xx ! 1.5128999999999999
print *, "single * double: x * xx = ", real(x,dp)*xx ! 1.5129000234603882
This last expression is exactly the same as the original expression, but it uses an explicit kind conversion rather than the implicit kind conversion. It should now be clear why the last expression is not the same as either of the two previous expressions.
Perhaps you are confused why the following almost equivalent program produces this output:
program precisions
use, intrinsic :: iso_fortran_env, only: sp => real32, dp => real64
implicit none
real(sp) :: x = 1.25
real(dp) :: xx = 1.25_dp
print *, "single * single: x * x = ", x*x
print *, "double * double: xx * xx = ", xx*xx
print *, "single * double: x * xx = ", x*xx
end program precisions
$ gfortran xxx.f90 && a.out
single * single: x * x = 1.56250000
double * double: xx * xx = 1.5625000000000000
single * double: x * xx = 1.5625000000000000
There is an important but perhaps subtle, difference in the two programs. Do you understand this output?
I don’t know how Matlab does mixed precision arithmetic, but if it does something different from fortran, I would think it would be difficult for programmers to use. As far as appending the kind values for constants of nondefault kind, there are tools that will do that automatically, but in this case you would need to be careful to avoid converting the values that are intended to be default kind. That is, the converted expression x=1.23_dp
might not be what is intended, and it would certainly be confusing for a human to look at that expression and to determine what was the original intent. Using compiler options to automatically promote kind values of variables and/or constants has similar issues, they can obscure or even conflict with the original programmer’s intent.