Scientific rendering of a real(dp) value.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | value | |||
| integer(kind=default_int), | intent(in) | :: | sig_digits |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=default_int), | private | :: | bump | ||||
| character(len=WORK_LEN), | private | :: | exact | ||||
| integer(kind=default_int), | private | :: | exp10 | ||||
| integer(kind=default_int), | private | :: | n_exact | ||||
| integer(kind=default_int), | private | :: | n_rounded | ||||
| logical, | private | :: | negative | ||||
| integer(kind=default_int), | private | :: | point_pos | ||||
| character(len=WORK_LEN), | private | :: | rounded | ||||
| integer(kind=default_int), | private | :: | sig | ||||
| logical, | private | :: | special |
pure function to_string_sci_dp(value, sig_digits) result(string) !! Scientific rendering of a `real(dp)` value. real(dp), intent(in) :: value integer(default_int), intent(in) :: sig_digits character(len=:), allocatable :: string character(len=WORK_LEN) :: exact, rounded integer(default_int) :: n_exact, point_pos, sig, n_rounded, bump, exp10 logical :: negative, special call special_text(value, string, special) if (special) return sig = max(1_default_int, min(sig_digits, PIC_FORMAT_MAX_SIG_DIGITS)) negative = is_negative(value) if (value == 0.0_dp) then ! Zero never carries a sign. Recognising a negative zero requires SIGN ! to distinguish the two signed zeros, which Fortran leaves processor ! dependent (F2018 16.9.165: the result is |A| if the processor cannot ! distinguish them), and Intel and AOCC do not distinguish them under ! their default fast floating point model. Emitting "-0.00" would ! therefore be compiler dependent, which is the one thing this module ! exists to avoid. A non-zero value that merely rounds to zero does ! keep its sign: SIGN is well defined for a non-zero argument. negative = .false. rounded = repeat("0", sig) exp10 = 0_default_int else call expand_exact(abs(value), exact, n_exact, point_pos) call round_decimal(exact, n_exact, sig, rounded, n_rounded, bump) ! A carry out of the leading digit turns "999" into "1000"; only the ! first sig digits are used, so the extra trailing zero is ignored and ! the decimal exponent moves up by one instead. exp10 = point_pos + bump - 1_default_int end if if (sig > 1_default_int) then string = rounded(1:1)//"."//rounded(2:sig) else string = rounded(1:1) end if string = string//"e"//exponent_field(exp10) if (negative) string = "-"//string end function to_string_sci_dp