1. Красивейший
гейзенбаг:
static void Main(string[] args)
{
float f = Sum(0.1f, 0.2f);
float g = Sum(0.1f, 0.2f);
//System.Console.WriteLine("f = " + f + " and g = " + g);
if (f == g)
{
System.Console.WriteLine("The sums are equal");
}
else
{
System.Console.WriteLine("The sums are Not equal");
}
Console.ReadKey();
}
static float Sum(float a, float b)
{
System.Console.WriteLine(a + b);
return a + b;
}
При запуске под отладчиком всё ок, при запуске релизной сборки под x86 без отладчика получаем "The sums are Not equal". При попытке
подсмотреть раскомментировать Console.WriteLine(), код начинает вести себя по-человечески. Поведение разрешено стандартом (в процессе вычислений значения с плавающей точкой необязательно будут округляться до float), но баг всё равно красивый. Объяснение
по ссылке.
2. Ещё один баг, но уже чуть попроще
static void Main(string[] args)
{
double d1 = 0.84551240822557006;
string s = d1.ToString("R");
double d2 = double.Parse(s);
bool s1 = d1 == d2;
Console.WriteLine(s1); // -> s1 is False
Console.ReadKey();
}
Формат "R" в теории должен обеспечивать безопасное преобразование в строку и обратно. По факту, всё работает нормально только для сборок под x86, в сборке рантайма под x64 закралась ошибка, причём со времён .Net2.0.
Объяснение.
Первый пример воспроизводится под .Net4 и выше, второй — начиная с .Net 2.0.
От себя:
1. Особую прелесть багам добавляет чехарда с платформами по умолчанию в разных версиях студии.
Начиная с vs 2012 в проектах по умолчанию
используется платформа anycpu32bitpreferred, причём в студии она отображается так же, как и вариант по умолчанию в VS2008, Any CPU. В VS 2010 по умолчанию предлагалась платформа x86, но только для exe-сборок, что тоже не добавляет очевидности.
Если нужно работать в нескольких версиях студии, за правильно выставленнной платформой уследить сложно, я сам пару раз попадался на эти грабли.
Ещё информация о изменении умолчаний в студии.
2. В тесты для всяких числодробилок однозначно стоит включать проверки и под x86, и под x64.
3. Stackoverflow крут! На оба вопроса ответы были получены за несколько часов
4. На еженедельную рассылку однозначно стоит подписаться. Подписка спрятана чёрти где,
вот инструкция.