1

In the code below, snapshot should be 0 if TrimCY = TrimBYS.

df <- df %>% 
   mutate(snapshot = case_when(Trend_direction != 2 ~ (TrimCY-TrimBYS)*sign(Trend_direction)*10/abs(Target_Snap-TrimBYS), 
                               TRUE ~ 10-((abs(TrimCY-Target_Snap)*10)/abs(Target_Snap-TrimBYS))))

When I execute this code on the data displayed below, this is not always the case. See snapshot values.

Trend_direction   Target_Snap   TrimCY   TrimBYS   snapshot 
1                 56            53       53        0.000000e+00 
1                 56            54       54        -3.552714e-14    
1                 56            55       55        -7.105427e-14    

Does anyone know why I am getting these very small non-zero results? When I copy the arithmetic function into the console and execute using the values above, it always comes out to 0.

kristenj
  • 31
  • 3

1 Answers1

1

These are floating point errors. To get the basic idea of what's going on, work out 1 - 1/3 - 1/3 - 1/3 = ? on a piece of paper, but only work to 3 decimal places. The equation looks like 1 - 0.333 - 0.333 - 0.333 = 0.001. Even though it should be zero, it's not. The computer is basically doing this, but to lots more decimal places and in binary.

For a more detailed explanation there are lots of resources around: for example: https://floating-point-gui.de/

You can get around it by rounding the answer, or (as akrun suggests) setting your options so these numbers display as zero.

This is why it's good practice to never test for x == 0 when x has been subject to these sorts of floating point calculations, and always do something like abs(x) < 1e-10 instead.

MattB
  • 651
  • 3
  • 11
  • Thank you very much for the thorough and helpful response. I have tried `options(scipen = 999)` but the numbers still do not display as zero. I will try rounding. – kristenj Aug 20 '20 at 18:06