How do I convert an inexact number smaller than $MinMachineNumber to machine-precision?
This situation is comparable to
$MinMachineNumber / 2
automatically giving an arbitrary precision result.
Precision[$MinMachineNumber/2]
(* 15.9546 *)
Mathematica detects the underflow condition and switches to arbitrary precision arithmetic. This can be turned off:
SetSystemOptions["CatchMachineUnderflow" -> False]
Now the result of $MinMachineNumber/2
has MachinePrecision
. The result is not 0.
, but a denormal number, I believe (my knowledge is lacking in this area). If you divide by a number larger than 10^$MachinePrecision
then you get a 0.
.
$MinMachineNumber/2
(* 1.11254*10^-308 *)
$MinMachineNumber/10^15
(* 2.5*10^-323 *)
$MinMachineNumber/10^16
(* 0. *)
SetPrecision
works as you want it, too.
number = 5.803736411761291186334053015446685`16*^-400;
number1 = SetPrecision[number, MachinePrecision]
(* 0. *)
SetPrecision
will not create denormal numbers, it seems.
SetPrecision[1.2`16*^-308, MachinePrecision]
(* 0. *)
number = 5.803736411761291186334053015446685`16*^-400;
number + 0.
(* 0. *)
N
makes arbitrary precision numbers when either given a second argument or a number not representable by a machine number as its first argument. However, machine numbers in expressions generally coerce arithmetic into the machine domain.
Another way:
toMPReal = Compile[x, x][#] &(*/.c_Compile :> RuleCondition[c]*);
toMPReal[5.803736411761291186334053015446685`16*^-400]
(* 0. *)
Uncomment the replacement rule to pre-compile the function.