Благодаря Hallgrim вот код, с которым я закончил:
ScreenCapture = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHbitmap(),
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(width, height));
я также закончил тем, что связал с BitmapSource вместо BitmapImage как в моем исходном вопросе
В общем случае нельзя предполагать, что ==
будет работать должным образом для типов с плавающей запятой. Сравните округленные значения или используйте вместо них конструкции типа abs (ab) <толерантность
.
Продвижение полностью на усмотрение компилятора (и будет зависеть от целевого оборудования, уровня оптимизации и т. Д.).
В этом конкретном случае почти наверняка происходит то, что значения хранятся в регистрах FPU с более высокой точностью, чем в памяти - в общем, современное оборудование FPU работает с двойной или более высокой точностью внутри, независимо от точности, которую требовал программист, с компилятор генерирует код для выполнения соответствующих преобразований, когда значения сохраняются в памяти; в неоптимизированной сборке,
При использовании gcc 4.3.2 утверждение не запускается, и действительно, rvalue, возвращаемое из x + y
, является float
, а не double
.
Так что все зависит от компилятора. Вот почему никогда не стоит полагаться на точное равенство двух значений с плавающей запятой.
Рабочий черновик для следующего стандарта C ++ 0x раздел 5, пункт 11:
Значения операндов с плавающей запятой и результаты выражений с плавающей запятой могут быть представлены с большей точностью и диапазоном, чем требуется типом; типы при этом не меняются
Так что на усмотрение компилятора.
Это проблема, поскольку преобразование числа с плавающей запятой в двоичное не дает точной точности.
А в пределах sizeof (float)
байтов он не может вместить точное значение числа с плавающей запятой и арифметические операции могут привести к приближению и, следовательно, равенству не удается.
См. ниже, например,
float x = 0.25f; //both fits within 4 bytes with precision
float y = 0.50f;
float z = x + y;
assert(z == x + y); // it would work fine and no assert
Я бы подумал, что это будет на усмотрение компилятора, но если бы вы так думали, вы всегда можете принудительно применить приведение?
Еще одна причина никогда напрямую не сравнивать числа с плавающей запятой.
if (fabs(result - expectedResult) < 0.00001)
В C++ FAQ lite есть дополнительное обсуждение этой темы: