[3/3] gdiplus: Make GdipInvertMatrix test pass on native

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Sat Jul 12 17:42:17 CDT 2008

```Am Samstag, den 12.07.2008, 16:55 -0500 schrieb James Hawkins:
> >>> -    GdipCreateMatrix2(1.0/9.0, 2.0/9.0, 4.0/9.0, -1.0/9.0, -2.0, -1.0,
> > Of course there's only one value of inverted matrix.
Which is not representable as a finite binary fraction.

> > GDI+ uses floating
> > point values for matrix elements so don't you think the result could be
> > slightly different due different calculation algorithms?
As they say: Never compare floating point numbers for equality. So I
understand your point. Especially if unrepresentable values are
involved.

> If you write and test the results in Windows, you won't have to guess
> what the results will be.
Right. Testing against Windows is the only method of verifying whether
Wine does the right things, but floating point arithmetic, which is
inherently prone to rounding errors, should IMHO be accounted for by
allowing slight variances.

> No I don't think the results will be
> slightly different.  Higher-precision arithmetic doesn't mean more
> slop.
What do you mean with higher-precision arithmetic? Floating point
arithmetic *always* means slop, as soon as numbers that can't be written
as finite binary fractions are involved. In this concrete case, I
suspect you are right. There is just one obvious algorithm to invert
a 2x2 Matrix, which is so simple that it cannot be stated in numerically
non-equivalent ways (remember, a+(b+c) is not necessarily equal to (a
+b)+c)), so I would expect the results to be really identical on windows
if the input numbers are small integers. Still, the fractions with nine
in the denominator make me worry. Couldn't we use a matrix with a
determinant of 8 or 16 instead of nine? This would make nice floats you
can definitely compare for equality.

As a side note: I don't like the implementation of m_equalf, as it
checks for absolute deviation instead of relative deviation. The values
used have the same order of magnitude as 1, so it does not matter for
this test. But: This very criterion is also used in in
GdipIsMatrixInvertible, where I consider it highly questionable, as long
as it is not backed by API tests.

Nikolay: Please write a test whether the matrix
1.0/131072, 2.0/131072, 4.0/131072, -1/131072, 0, 0
is invertible. According to your criterion, it is *not* invertible, as
the determinant will be 9.0/17179869184, which is way below 1e-5, but
this matrix still *is* invertible. What happens on Windows?

Regards,
Michael Karcher

 Which I found (as expected) when looking at dlls/gdiplus/matrix.c

```