Двоичное представление для 0.1:
System.out.println(new BigDecimal(0.1));
печать
0.1000000000000000055511151231257827021181583404541015625
Когда вы печатаете 0.1, вы получаете небольшое количество округлений, которое скрывает эту ошибку.
При выполнении вычисления необходимо использовать BigDecimal или округлить результат или преобразовать вычисление, чтобы минимизировать ошибку.
5 % 0.1
(5 / 0.1 % 1) * 0.1
50 % 1 / 10
С точки зрения двойного вы можете сделать
double d = 5;
double mod0_1 = d * 10 % 1 / 10;
double rounded = Math.round(mod0_1 * 1e12)/1e12; // round to 12 places.
Примечание: в результате все равно может быть небольшая ошибка, но она будет достаточно маленькой, чтобы при печати ее не было видно.