2015-07-31 3 views
3

У меня есть следующая строка кода, которая производит 2 разных результата.Math.Round производит разные результаты в зависимости от того, где он запущен

Учитывая следующую строку

var rounded = Math.Round(415 * 0.01f, 1); 

Я бы ожидать, что это раунд 4.2 все время. Когда я запускаю это из консольного приложения, я всегда получаю ожидаемый результат 4.2. Если я поместил одну и ту же строку в единичный тест и запустил этот тест, я в итоге получим 4.1. Я также получаю 4.1, если строка работает в службе Windows.

Любые мысли о том, почему это произвело бы другое значение или как заставить его вести себя последовательно?

Запуск этого с визуальной студией 2013 года на 64-битной машине с .NET 4.5.

+0

Не ключ. Похоже, что этот вызов перенаправляется на extern, хотя может иметь какое-то отношение к нему. – BradleyDotNET

+1

При округлении средних значений алгоритм округления выполняет тест равенства. Из-за проблем двоичного представления и точности в формате с плавающей запятой значение, возвращаемое методом, может быть неожиданным. Для получения дополнительной информации см. Округление и точность. https://msdn.microsoft.com/en-us/library/system.math.round(v=vs.110).aspx#Precision –

+1

Когда я пытаюсь выполнить код в консольном приложении, я получаю '4.1'. Я думаю, что проблема в том, что вы ожидаете, что результат вычисления будет * точно * '4.15', а это не так. Это '4.14999990724027', потому что' 0.01f' не точно '0.01', а' 0.00999999977648258'. Если вы используете 'Math.Round (4.15, 1)', вы получите '4.2'. – Guffa

ответ

-1
var rounded = Math.Round(415 * 0.01d, 1); 

можно использовать дважды, чтобы заменить флоат

Точность недостаточно

+0

удваивает значения с плавающей запятой - https://msdn.microsoft.com/en-us/library/678hzkk9.aspx – iliketocode

+0

Двойной бит 64 бит – zhouqh2013

0

Много лет назад у меня была аналогичная проблема. Через некоторое время после запуска мое приложение вычисляло двойные значения с одной точностью и через некоторое время - с другой точностью. Это было очень странно.

Через некоторое время я понял, что в какой-то момент приложение инициализирует DirectX стандартными флагами, а DX, в свою очередь, изменяет точность FPU с двойными значениями.

Итак, в качестве совета, пожалуйста, проверьте смежный код на наличие побочных эффектов. (проверьте использование DirectX, проверьте использование внешних неуправляемых DLL)

PS: Нет волшебства. Не путайте. И попробуйте уменьшить использование десятичного разряда. Это самая медленная вещь над OLE ...

Смежные вопросы