Ошибка округления в C #: разные результаты на разных ПК - PullRequest
0 голосов
/ 24 октября 2009

У меня есть функция в C #, которая возвращает следующее:

...
float amount = smallestPercentage * (float)quantity;
return (int)amount;

Теперь я знаю, что я должен использовать Convert.Int32 (количество), а не тип приведения типа int, и это решило проблему. Но моя проблема была действительно в этом ...

При разработке моей программы дома (Windows Vista) я получаю возвращаемое значение 1, но при развертывании программы в другой среде (Windows XP) я получаю возвращаемое значение 0.

Мне было интересно, связано ли это с версией Windows, версией .NET или даже процессором ЦП?

Спасибо.

David

Ответы [ 2 ]

8 голосов
/ 24 октября 2009

На самом деле, вы можете получить разные результаты:

  • на разных машинах

  • в зависимости от того, были ли вы скомпилированы с настройками отладки или розничной сборки

  • в зависимости от того, делали ли вы вычисления в константах времени компиляции или во время выполнения

  • как локальные переменные и другие временные значения используются в вашем методе

  • и т. Д.

Спецификация C # призывает к тому, что арифметика с плавающей запятой может быть выполнена с большей точностью, чем вы ожидаете. Это никогда не достигается с меньшей точностью, чем вы ожидаете, но мы оставляем за собой право использовать алгоритмы с более высокой точностью на определенном оборудовании и с некоторыми доступными оптимизациями, каждый раз, когда дрожание думает, что это может сойти с рук , Это означает, что в операциях, которые очень чувствительны к небольшим изменениям в точности - например, округление - могут давать совершенно разные результаты, по-видимому, без объяснения причин.

Вы не первый пользователь переполнения стека, обнаруживший этот факт: Проблема с преобразованием из int в float

2 голосов
/ 24 октября 2009

При работе с числами с плавающей запятой очень желательно, чтобы вы использовали какую-то процедуру округления. В C # я считаю, что лучшим подходом является метод Math.Round .

Что касается того, почему это происходит, разные процессоры имеют разные процедуры для вычисления чисел с плавающей запятой и двойников. На вашей целевой машине вы, вероятно, получите значение чуть ниже 1 (скажем, .999987), которое, когда приведение будет преобразовано в 0. Число с плавающей запятой существует с момента создания CLR, так что это, скорее всего, вещь, специфичная для процессора. Операционные системы очень редко мешают прямому коду приложения.

...