Paradoksalt nok, så får man problemer, når man skal teste med tal-typer med stor nøjagtighed. Jeg oplevede det første gang, i forbindelse med udregninger af rotationer i Vector3 i MDX. I starten var jeg ret forundret over, at der var så stor unøjagtighed på en PC i det andet millennium. Det hænger selvfølgelig sammen med afrundigsfejl, i de forskellige algoritmer, men hvordan tester man så med disse unøjagtigheder? Tag følgende test: Kvadratroden af 2 i anden skal være lig med 2.
[code=csharp][TestMethod]
public void Frem_og_tilbage()
{
double sqr = Math.Sqrt(2d);
double sq = sqr * sqr;
Assert.AreEqual
(2, sq,
"Frem og tilbage er ikke det samme");
}
[/code]
Den fejler med følgende kryptiske fejl: Assert.AreEqual failed. Expected:<2>. Actual:<2>. Frem og tilbage er ikke det samme – 2 er ikke 2!
Sætter man et breakpoint, og ser på værdierne i debuggeren, ser man at: sq = 2.0000000000000004, hvilket jo klart nok ikke er 2.
Den generiske udgave af AreEqual er ikke helt god nok, når det kommer til sammenligning af tal med høj nøjagtighed, og man føler et behov for en overload, med angivelse af en afvigelse. Ser man derimod efter på den almindelige udgave af AreEqual, finder man straks det man søger, og man er i stand til at lave følgende test, der tager højde for usikkerheden i System.Math.
[code=csharp][TestMethod]
public void Frem_og_tilbage_er_lige_langt()
{
double sqr = Math.Sqrt(2d);
double sq = sqr * sqr;
Assert.AreEqual(2, sq, 0.000001d,
"Frem og tilbage er ikke det samme");
}
[/code]
Green Lights makes me happy…