I think a solution based on pattern matching will be much faster than ones based onusing Element
(which is more mathematical in usagenature) or only pattern tests or anythignanything else that forces evaluation, since we can bypass the main evaluator. However, it is not possible to completely escape evaluation, because there can be infinitely large number of possibilities for a real number that cannot be matched solely by pattern matching. Hence, the following tries to delegate as much as possible to the pattern matcher and evaluates only what's necessary. The unfortunate consequence is that it is no longer immune to prank entries such as Unevaluated@Pause@10
.
ClearAll@realQ
SetAttributes[realQ, Listable]
realQ[_Real | _Integer | _Rational] := True
realQ[Catalan | ChampernowneNumber | Degree | E | EulerGamma | Internal`Euler2Gamma |
Glaisher | GoldenRatio | Khinchin | MachinePrecision | Pi] := True
realQ[Complex[_, 0.]] := True
realQ[_]realQ[x_] := FalseNumericQ[x]
realQ[{"text", 0, 3.0, 1/2, I, Pi, 1 + 0. I}]
(* {False, True, True, True, False, True, True} *)
The list in the second definition was obtained using
Select[Names["*`*"], MemberQ[Attributes@#, Constant] &]