9
$\begingroup$

Suppose I want to have a function (call it NLess) that given two real numeric quantities, a and b, it returns True if a is smaller than b, ignoring precision. Here are some test cases:

NLess[3.14`1, Pi]
NLess[4.49999999999999`,4.50000000000001`]
NLess[E, Pi]
NLess[3.14159265358979323846263`22, Pi]
NLess[4.49`1, 9/2]
NLess[E, 2.782`1]

All of these should return True. The usual Less function only returns true for Less[E, Pi]:

Less[3.14`1, Pi]
Less[4.49999999999999`,4.50000000000001`]
Less[E, Pi]
Less[3.14159265358979323846263`22, Pi]
Less[4.49`1, 9/2]
Less[E, 2.782`1]

False

False

True

False

False

False

I have some code to do this, but I find it unsatisfactory.


One further detail. It is acceptable to me to have both:

 N[3.14`1, 3.14`100]
 N[3.14`100, 3.14`1]

be false, or one or the other to be True, but it would be nice if this behavior could be controlled

$\endgroup$
  • $\begingroup$ I take it that 3.14`1 should be treated as though it were 3.14 exactly and that that the machine precision (MP) number 4.49999999999999` should be treated as 5066549580791797/2^50 if MP = binary64 (which might depend on machine precision)? Or should MP numbers be rounded to their decimal equivalents displayed by InputForm? $\endgroup$ – Michael E2 Jan 26 '17 at 2:17
  • 2
    $\begingroup$ Is this "satisfactory? NLess[a_, b_] := Less[Rationalize[ SetPrecision[a, Max[MachinePrecision, Precision[a]]], 0], Rationalize[SetPrecision[b, Max[MachinePrecision, Precision[b]]], 0]]. It actually only works because, to my surprise, Rationalize[Pi,0] still gives Pi (which is not a rational number). $\endgroup$ – Felix Jan 26 '17 at 2:17
  • $\begingroup$ @Felix Should NLess[0.3333333333333333`, 1/3] return True? $\endgroup$ – Michael E2 Jan 26 '17 at 2:22
  • $\begingroup$ Indeed, the working precision must be increased beyond the provided precision. How about this? NLess[a_, b_] := Less[Rationalize[ SetPrecision[a, Max[MachinePrecision, Precision[a]] + 1], 0], Rationalize[ SetPrecision[b, Max[MachinePrecision, Precision[b]] + 1], 0]] $\endgroup$ – Felix Jan 26 '17 at 2:26
  • 1
    $\begingroup$ But is 4.49999999999999` identical to double-precision floating-point fraction 5066549580791797/2^50 or to decimal input fraction 449999999999999/10^14? It can't be both. And what to do about comparing it to 4.49999999999999`15 would seem to depend on the answer. I would have assumed it was the internal binary representation, but somehow you've made me doubt that. $\endgroup$ – Michael E2 Jan 26 '17 at 2:54
1
$\begingroup$

How about this?

NLess[a_, b_, p_: 1000] := Order @@ N[{a, b}, p] == 1

The third (optional) parameter $p$ controls the precision used for exact numbers and numbers with precision greater than $p$. Order appears to ignore Internal`$SameQTolerance etc.

$\endgroup$
  • $\begingroup$ Mr.Wizard what does the : 1000 near the pattern do? i have never seen it before $\endgroup$ – Alucard Sep 2 '17 at 12:44
  • $\begingroup$ @Alucard FullForm[p_: 1000] gives Optional[Pattern[p, Blank[]], 1000] so you should look at Optional $\endgroup$ – Mr.Wizard Sep 2 '17 at 12:45
  • $\begingroup$ ah got it , thank you $\endgroup$ – Alucard Sep 2 '17 at 12:47

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.