# Rem function in Octave showing wrong result

I am trying to write an if statement that checks if 2 numbers are divisible before running some commands. The problem is, the rem function is giving some wrong results for certain number (2 is definitely divisible by 0.5, 0.4, 0.2 and 0.1 but the function says otherwise). A reproduction of the error is posted below

t=2
h=1

while h>0
if rem(t,h)==0
disp ('divisible')
else
disp('non divisible')
endif
h-=0.1
endwhile


The result in the command indow is

>> t =  2
h =  1
divisible
h =  0.90000
non divisible
h =  0.80000
non divisible
h =  0.70000
non divisible
h =  0.60000
non divisible
h =  0.50000
non divisible
h =  0.40000
non divisible
h =  0.30000
non divisible
h =  0.20000
non divisible
h =  0.10000
non divisible
h =    1.3878e-16
divisible
h = -0.100000


Any solution is much appreciated

• Floating point. – A rural reader Apr 5 at 13:45

$$0.1$$ is not exactly representable in double precision arithmetic, and it will be rounded. The double precision representation of $$0.1$$ is
$$\verb|00111111 10111001 10011001 10011001 10011001 10011001 10011001 10011010|,$$
which is $$0.100000000000000005551115123126$$. As you can see, if you compute $$h$$ by subtracting "$$0.1$$" from it repeatedly, you actually do not get $$0.1$$, $$0.2$$, $$0.4$$ or $$0.5$$ exactly, just approximately. So it is not surprising that the rem function does not return divisible. If you try $$\verb|rem(2,0.5)|$$, you will see that it returns "divisible" as many powers of 2 are exactly representable in double precision.
• I don't like that solution very much though. Consider $\verb|rem(2,1-eps(1))=4.4409e-16|$ which could be considered to be below the tolerance but $0.9999999999999998$ does not divide $2$. Depending on the application, an error like this may be very harmful. – Abdullah Ali Sivas Apr 5 at 0:39