I am struggling with some puzzling machine-underflow errors that I can't reduce to a form that makes sense to me, and I would like some help understanding what Mathematica is doing and what it is (or I am) getting wrong.
This comes from a bigger problem, but I've tried to reduce it as much as possible and this is the simplest instance that I can find:
Block[{ζ = 200},
{#, N[#]} &[
ζ^(3/2) Sqrt[1/( -1 + (E^(4 ζ)) )]
]
]
On my machine, the instance itself evaluates reasonably well (to 2000 Sqrt[2/(-1 + E^800)]
), but the N[#]
'd version produces a General::munfl
error and returns a value of 0.
. This error goes away if:
- I eliminate the
-1
from the denominator, which makes sense; but also - if I remove the factor of
ζ^(3/2)
and - if I change the
ζ = 200
assignment toζ = 200.
,
and the latter two make no sense to me.
Could one of you wizards shed some light on this weird stuff? What is causing this behaviour, and how do I avoid it?
(And more generally: This comes from a function that is defined via a symbolic integration. (More details available if they are relevant.) The best outcome would be a numerical-handling procedure that I can apply to the results of that symbolic integration that will prevent errors like these from creeping in.)
Edit: OK, I've been able (I think) to narrow down the source of the flagged error (or at least one of them). The N[#]
evaluation seems to be going through a multiplication of the form
(8.`*^6 )*(3.6`2*^-348)
(where the 3.6`2
is actually to precision $\sim$13.05...
, but that seems not to affect the output) which produces the error message
General::munfl: $8.\times 10^6 \ 3.6\times 10^{-348}$ is too small to represent as a normalized machine number; precision may be lost.
and returns the value 0.
. This feels completely bonkers to me: if 3.6`2*^-348
is a perfectly fine number, why would making it bigger by a factor of a million suddenly make it too small to handle?
Zooming out a bit, the problem seems to be that the factor of 8.`*^6
(which for this example ultimately comes from the $\zeta^{3/2}$, but in general could be anything that multiplied the 3.6`2*^-348
) is at machine precision, whereas the result of the exponential,
InputForm[Exp[800.]]
(*2.726374572112566567364779546367269757967`13.051499783199061*^347*)
is not. How can this be avoided?
N[...,20]
. $\endgroup$Exp[800.]
cannot be, and is not according to theInputForm
, represented at machine precision. On overflow such as this, the number is promoted to arbitrary precision. However, on underflow, the result becomes machine zero (since V11.3). Compare{1/Exp[800.], Exp[-800.]}
. -- If the factors are positive reals, tryBlock[{ζ = 200}, {#, Exp@N[PowerExpand@Log@#]} &[ζ^(3/2) Sqrt[1/(-1 + (E^(4 ζ)))]]]
. I cannot guarantee it will always work, though, but it works on your expression. $\endgroup$N
twice; first with arbitrary precision then with machine precision. For example,Block[{ζ = 200}, {#, N[#, 20] // N} &[ζ^(3/2) Sqrt[1/(-1 + (E^(4 ζ)))]]]
$\endgroup$