6

Is there a fast function "ExactExpressionQ" to test whether an expression is exact vs inexact? I'm looking for something like ExactNumberQ that works for expressions.

My attempt at this is

ExactExpressionQ[expr_] := FreeQ[expr, _Real|_Complex?InexactNumberQ]

ExactExpressionQ[0]
ExactExpressionQ[0.]
ExactExpressionQ[(2.1 + I) x]
ExactExpressionQ[Sin[x]]

(* True *)
(* False *)
(* False *)
(* True *)

Is there something better?

QuantumDot
  • 19,601
  • 7
  • 45
  • 121
  • 1
    Is it OK that e.g. Floor[1.4*x] is treated as inexact? I think Floor always produces exact integers if given numbers, whether exact or inexact. – Marius Ladegård Meyer Jun 04 '16 at 13:42
  • That's a good point; one would have to think about certain functions returning exact results even if their input may be inexact. For the case at hand, let's just ask that ExactExpressionQ tests whether the input expression is literally exact or not. – QuantumDot Jun 04 '16 at 14:07
  • One issue is that Complex can head an exact number. Have to peek inside... – John Doty Jun 04 '16 at 14:28
  • 1
    You can shorten your definition to ExactExpressionQ[expr_] := FreeQ[expr, _?InexactNumberQ] – Bob Hanlon Jun 04 '16 at 14:29
  • @BobHanlon That's a good point. Do you think it might be slower, though? It has to PatternTest every piece of expr, whereas what I have PatternTests only if there is something with head Complex. – QuantumDot Jun 04 '16 at 14:35
  • @BobHanlon I just tried both versions out with a few really long expressions I have which pass as True (worst case), and I'm finding what I have so far is between 2 and 8 times faster. – QuantumDot Jun 04 '16 at 14:40
  • 1
    It seems giving levelspec -1 would help and still give the desired result. (Can't test here though). – george2079 Jun 04 '16 at 15:06
  • @george2079 Yep, giving levelspec {-1} improves speed by factor 2. – QuantumDot Jun 04 '16 at 15:24

1 Answers1

1

Using george2079's suggestion, the code can be tweaked to

ExactExpressionQ[expr_] := FreeQ[expr, _Real|_Complex?InexactNumberQ, {-1}]

for better performance.

QuantumDot
  • 19,601
  • 7
  • 45
  • 121