0

Can someone please explain these results to me? I assume it has something to do with how the value of -1 is stored in the vector "dev"...

enter image description here

As mentioned in the comment below:

enter image description here

Dan
  • 103
  • 1
  • 16
  • 1
    What does `dev[j] == -1` return? I'm guessing FALSE because it's not exactly equal to -1. Likely this is just a duplicate of: https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal This likely doesn't have anything to do with the modulus operator in particular, it just has to do with floating point math. – MrFlick Nov 05 '20 at 20:59
  • @MrFlick - Thank you for the response (see edit above). So, its my understanding that because of the limitations of floating-point arithmetic, dev[j] is stored NOT exactly equal to -1. I see in the thread you linked to (thank you for the link, btw) that they suggest using all.equal() instead of ==. Can someone suggest a similar workaround for %%? – Dan Nov 05 '20 at 21:38
  • 1
    What is your goal? If you are trying to identify integers in `dev`, then set a tolerance `tol = 1e-12` and do something like `abs(dev - round(dev)) < tol` – Gregor Thomas Nov 05 '20 at 22:01
  • You didn't show us how you produced `dev`. The value -1 can be stored exactly in floating point, but many other values also print as `-1.00`. – user2554330 Nov 05 '20 at 22:38

1 Answers1

1

(edited to add Best Answer)

Best answer

As pointed out by Ben Bolker in the comments, there is a classic answer already, which covers my points and more besides:

Why are these numbers not equal?

Short answer

all.equal is your friend. When comparing floating point numbers, use it instead of ==. e.g. all.equal(dev[j], -1)

Long answer

This is floating-point arithmetic; floating-point numbers are rarely exactly the same, due to rounding errors. This isn't an R thing; it's a computer thing.

In this case, the modulo operator is doing exactly what the documentation says: it's returning the remainder after division. In this case, the remainder is noise, which is expected.

You can compare with

all.equal(dev[j] %% 1, 0)

Floating-point traps are covered quite nicely in chapter 1 of the R Inferno: https://www.burns-stat.com/pages/Tutor/R_inferno.pdf

Whenever floating point operations are done, even simple ones, you should assume that there will be numerical error. If by chance there is no error, regard that as a happy accident, not your due. You can use the all.equal function instead of == to test equality of floating point numbers.

Jason
  • 2,379
  • 19
  • 25
  • 1
    there's also a [classic SO post about this](https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal/9508558#9508558) – Ben Bolker Nov 05 '20 at 22:43