2
$\begingroup$

Upon doing a simple subtraction 13.725 - 13.5 both Mathematica 11.3 and 12.0 beta version are giving me 0.22499999999999964 although both display the answer as 0.225. Is there a way to yield the answer in exact form. For now I can only use SetPrecision to address the issue:

SameQ[0.22499999999999964, 0.225] && Equal[0.22499999999999964, 0.225]

(*False*)

SameQ[SetPrecision[0.22499999999999964, 4], 0.225] && Equal[SetPrecision[0.22499999999999964, 4], 0.225]

(*True*)

I have a code with some degree of complexity and I am going to simplify the problem a bit here. lets say i have two points with (x,y,z) coordinates and i want to say that the translation of a point by a vector: {13.725, 0.8397114317029974, 0.46748599816306713} - {13.50, 0., 0.} = {0.22499999999999964, 0.8397114317029974, 0.46748599816306713} is equal to a point 'b' {0.225, 0.8397114317029974, 0.46748599816306713}. How can this be done easily?

$\endgroup$
  • 2
    $\begingroup$ tried Rationalize? $\endgroup$ – kglr Mar 14 at 13:55
  • 8
    $\begingroup$ "how to prevent Mathematica from giving inexact answers" - cheeky answer: don't start with inexact input in the first place $\endgroup$ – J. M. will be back soon Mar 14 at 14:04
  • 5
    $\begingroup$ What you want can be effected for print purposes, but numerically it is basically not possible. Such are the vagaries of going from decimal to binary and back to decimal, all in finite precision. $\endgroup$ – Daniel Lichtblau Mar 14 at 14:19
  • 1
    $\begingroup$ @DanielLichtblau i understand what you are saying but on a simple calculator when i do 13.725 - 13.50 I get 0.225 .. But not in Mathematica. I think i have a misunderstanding about how inexact numbers work in computer and a hand held calculator $\endgroup$ – Ali Hashmi Mar 14 at 14:37
  • 3
    $\begingroup$ I believe some calculators use BCD (binary coded decimal). A calculator that uses BCD arithmetic will not have decimal-to-binary-to-decimal conversion issues. See for example this page $\endgroup$ – Daniel Lichtblau Mar 14 at 16:14
1
$\begingroup$

With the numbers in your example, equality testing with Equal (i.e. ==) already works:

pointA = {13.725, 0.8397114317029974, 0.46748599816306713};
transVec = {13.50, 0., 0.};
pointB = {0.225, 0.8397114317029974, 0.46748599816306713};

pointA - transVec == pointB
(* True *)

This is because Equal considers approximate numbers with machine precision equal "if they differ in at most their last seven binary digits (roughly their last two decimal digits)" (from the Details section of its docs).

However, that threshold may not be appropriate for you, so you can use other methods. For instance, evaluate the distance between the two points (e.g. with Norm) and check whether it is less than an appropriate threshold:

Norm[(pointA - transVec) - pointB] < 10 $MachineEpsilon
(* True *)

Note, however, that the above will remain unevaluated if its truth value cannot be decided. For instance, imagine that, contrary to your expectation, a symbol does not have a numerical value (here I am using pointC without having assigned it a value):

Norm[(pointA - transVec) - pointC] < 10 $MachineEpsilon

Sqrt[Abs[0.22499999999999964 - pointC]^2 + Abs[0.46748599816306713 - pointC]^2 + Abs[0.8397114317029974 - pointC]^2] < 2.220446049250313*^-15

That may or may not be desirable (that's your design decision); if you want to avoid it, though, you can wrap the inequality in TrueQ:

TrueQ[Norm[(pointA - transVec) - pointC] < 10 $MachineEpsilon]
(* False *)
$\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.