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$
14
  • $\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, 2017 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, 2017 at 2:17
  • $\begingroup$ @Felix Should NLess[0.3333333333333333`, 1/3] return True? $\endgroup$
    – Michael E2
    Jan 26, 2017 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, 2017 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, 2017 at 2:54

1 Answer 1

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$
3
  • $\begingroup$ Mr.Wizard what does the : 1000 near the pattern do? i have never seen it before $\endgroup$
    – Alucard
    Sep 2, 2017 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, 2017 at 12:45
  • $\begingroup$ ah got it , thank you $\endgroup$
    – Alucard
    Sep 2, 2017 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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