Почему разные результаты 0.5 mod 0.1 на разных языках программирования?

У меня вопрос о модуле. Операция modulo находит остальную часть деления одного числа на другое. Я ожидал, что результат 0.5% 0.1 = 0. Но когда я запускаю это на PHP или .net, я получаю 0,1.

Код в php, который я запускал, был:

var_dump(fmod(0.5, 0.1)); 

В .net я испробовал следующее:

 Console.WriteLine(0.5%0.1); 

Я также попробовал онлайн-калькулятор http://www.calculatorpro.com/modulo-calculator/ .

Все эти 3 метода дали мне 0,1 в качестве ответа.

Но когда я печатаю это в google, я получаю результат, который я ожидал http://www.google.nl/search?source=ig&hl=nl&q=0.5%20mod%200.1&meta= .

Является ли это ошибкой в ​​.net / php или Google знает правильный ответ? Может ли кто-нибудь объяснить, почему возникают эти различия?

    Число, которое вы получаете на PHP или C # или C ++ или Python или что-то еще, когда вы запрашиваете 0,1, – это число с плавающей запятой с двойной точностью, что означает, что это конечная «десятичная» – с 53 значащими битами, включая первые 1-битные – – в базе 2. На самом деле то, что вы получите, является ближайшим точно представимым числом до 0,1, что, я думаю, составляет ровно 0,1000000000000000055511151231257827021181583404541015625.

    С другой стороны, 0.5 является конечным «бицималом»; ценность, которую вы получите, когда вы попросите об этом, будет равна 0,5.

    Поэтому 0,5 всего лишь немного меньше, чем в 5 раз «0,1», поэтому «0.5 mod 0.1» на самом деле дает вам что-то немного меньше 0,1. На самом деле, я думаю, что это точно 0.09999999999999997779553950749686919152736663818359375.

    Теперь, когда вы задаете PHP или C # или что-то еще, чтобы отобразить этот номер, он отобразит некоторое количество цифр. Вы действительно не хотите, чтобы это отображало всю ужасную вещь. (Подумайте: предположим, вы просто попросите отобразить 0,1, вам нужно чудовищное чудовище, или вы хотите «0,1»? Думали так.) И число на самом деле очень близко к 0,1; если вы не запросите более 15 цифр точности, то правильная вещь для отображения – всего лишь «0,1».

    Наблюдайте (это Python, с которым мне было удобно):

     >>> for n in range(10,20): print (("%%.%dg"%n)%(0.5%0.1)) 0.1 0.1 0.1 0.1 0.1 0.1 0.09999999999999998 0.099999999999999978 0.0999999999999999778 0.0999999999999999778 

    Итак: не ошибка; на самом деле вопрос о плавающей запятой не подходит для «точных вычислений» (иногда это уместно, иногда нет, дело в том, чтобы понять, что он делает и что вам нужно); может или не может указывать на то, что вы бы лучше использовали целые числа, в зависимости от вашей реальной потребности.

    Чтобы узнать больше об этом, чем вы, вероятно, хотите узнать, взгляните на «Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой» .

    Что касается того, почему калькулятор Google дает ожидаемый ответ 0, я не знаю. Возможно, они используют десятичную арифметику – реальные номера базы-10 – чтобы свести к минимуму неожиданные сюрпризы. (Это, как правило, намного медленнее, чем использование встроенной с плавающей запятой, но у Google есть много доступных процессоров, и я делаю ставку только на небольшую часть работы, которую их машины обработки изображений имеют какое-либо отношение к калькулятору.)

    Нет, это не ошибка, так как операция modulo может быть определена и с номерами с плавающей запятой. В вашем PHP-коде вы явно используете fmod() вместо % и в .NET оператор % определен для каждого числового типа ( контрольная ссылка )

    0 – целочисленный ответ, а 0,1 – результат правого поплавка

    дополнительно посмотреть на wolframalpha: http://www.wolframalpha.com/input/?i=0.5+mod+0.1

    Если вы хотите оценить 0.5%0.1 , вы, вероятно, могли бы (и должны) использовать целочисленную арифметику. Например, если вы вычисляете что-то, связанное с валютой, обычно лучше хранить количество центов как целое число, чем хранить сумму в виде числа с плавающей запятой.