6
$\begingroup$

Is it possible to obtain the machine precision (double) version of Infinity? This is useful when using LibraryLink and C functions that accept doubles: passing Infinity raises a type error, because Infinity is a symbol.

$\endgroup$
  • $\begingroup$ something like $MaxMachineNumber? $\endgroup$ – chuy Apr 14 '14 at 16:14
  • $\begingroup$ @chuy: $MaxMachineNumber is the largest finite number the machine's native floating point type can represent. But IEEE floating point numbers can also represent plus and minus infinity. I guess he means those. $\endgroup$ – Niki Estner Apr 14 '14 at 16:48
  • $\begingroup$ @nikie that makes sense $\endgroup$ – chuy Apr 14 '14 at 17:18
  • 2
    $\begingroup$ I think that it is not possible. It's possible to get these special floating point values into Mathematica, but they'll cause all sorts of problems and it's not possible to do reliable operations on them. Things fail randomly. My opinion is that it's not worth the risk to push it. More info here: mathematica.stackexchange.com/questions/19026/… $\endgroup$ – Szabolcs Apr 14 '14 at 17:30
4
$\begingroup$

Yes, it's possible, and safe, provided that you do it inside the VM and not in top-level code. (Szabolcs's question provides the proof that dealing with these at top level is not safe; the values are not handled even slightly correctly.) This is reasonable to do for LibraryFunctions, because they can be called efficiently from the VM.

First we need a LibraryFunction that can distinguish a floating-point infinity:

infinityQ = With[{$MaxMachineNumber = $MaxMachineNumber},
   Compile[
    {{x, _Real, 0}}, If[x > $MaxMachineNumber, True, False],
    CompilationTarget -> "C"
   ]
  ];

libfuncinfinityQ = Last[infinityQ]
(* -> LibraryFunction[<>, compiledFunction0, {{Real, 0, Constant}}, True|False] *)

Now we test it:

With[{
   $MaxMachineNumber = $MaxMachineNumber,
   $MachineEpsilon = $MachineEpsilon
  },
 Compile[{},
   libfuncinfinityQ[(1 + $MachineEpsilon) $MaxMachineNumber (* makes an infinity *)]
 ][]
]
(* -> True *)

Note that this was done just using the VM, without producing another LibraryFunction. (That is, the call comes from Mathematica, not compiled C code.)

For completeness:

libfuncinfinityQ[$MaxMachineNumber]
(* -> False *)

Note that even though you can work with infinite or not-a-number values normally inside the VM, it is not possible to pass them between there and the top level (to do so produces an error). However, trying to pass these same values back out of a LibraryFunction causes them to be substituted with DirectedInfinity[+1|-1] (but not ComplexInfinity, which does not exist in IEEE754) and Indeterminate, which is (hopefully) not as problematic.

Cautionary note

As I mentioned here, arithmetic operations in the VM do not treat not-a-number values as they should be treated according to IEEE754. One should beware of similar pitfalls concerning the infinities; in particular, comparing them with other values could lead to problems. On the other hand, it is safe to produce these values, so if one just needs them for the purposes of supplying them as arguments to other functions, then these arithmetic issues may never arise.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.