[Mono-list] MS doc discrepencies
Jon Guymon
gnarg@slackworks.com
Wed, 27 Feb 2002 11:49:28 -0800
This is a multi-part message in MIME format.
------=_NextPart_000_0000_01C1BF84.CFDF22E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 8bit
The class I'm testing is System.Math.
Here are the question areas:
operation docs result
Log(0) PositiveInfinity NegativeInfinity
Log(0, y) PositiveInfinity NegativeInfinity
Log10(0) PositiveInfinity NegativeInfinity
Pow(x, NegativeInfinity) 0 NaN
Pow(x, PositiveInfinity) PositiveInfinity NaN
that's it I think
I am admittedly /not/ a math buff, but I think I did everything correctly.
In any event I have attached the code for checking and cross-posting and
stuff. The trouble spots are commented.
Oh, by the way, where can I get my hands on IEEE specs for these operations?
thanks,
jon
-----Original Message-----
From: Ben Houston [mailto:ben@exocortex.org]
Sent: Tuesday, February 26, 2002 8:40 PM
To: 'Jon Guymon'
Subject: RE: [Mono-list] MS doc discrepencies
Hi Jon,
Just out of curiosity what behavior differs between the docs and the
actual classes? I'm a bit of a math buff and am currently writing a
DSP library in C# thus I'm interested. :-)
And if it helps I would suggest going with the behavior that is most
adherent to numerical methods standards (i.e IEEE, etc...).
Take care,
-ben houston
http://www.exocortex.org/~ben
> -----Original Message-----
> From: mono-list-admin@ximian.com [mailto:mono-list-admin@ximian.com]
On
> Behalf Of Jon Guymon
> Sent: Wednesday, February 27, 2002 1:26 AM
> To: mono-list@ximian.com
> Subject: [Mono-list] MS doc discrepencies
>
> Hello,
>
> I've been working on MonoTests.System.MathTest, running it with the
> Microsoft runtime, and testing the Microsoft classes. What I found is
> that
> in a couple of cases the Microsoft System.Math class does not behave
as
> the
> documentation describes it.
>
> This makes me wonder which I should treat as law. Should I write the
> tests
> to they follow the docs to the letter, or should I write them so they
all
> pass when run against the Microsoft classes?
>
> It seems to me that the docs should be trusted over the
implementation,
> but
> I want to check before I submit something.
>
> It's also possible I'm doing something wrong. I'll send my code to
> whoever
> wants to proof it, but I don't want to clutter the mailing list just
yet
> ^_^.
>
> Also, assuming this all gets worked out, should I simply post the code
to
> this list?
>
> Thanks
> Jon
>
>
>
> _______________________________________________
> Mono-list maillist - Mono-list@ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
------=_NextPart_000_0000_01C1BF84.CFDF22E0
Content-Type: application/octet-stream;
name="MathTest.cs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="MathTest.cs"
// MathTest.cs
//
// Jon Guymon (guymon@slackworks.com)
//
// (C) 2002 Jon Guymon
//=20
using System;
using NUnit.Framework;
namespace MonoTests.System=20
{
public class MathTest : TestCase {
=09
public MathTest() : base ("System.Math testsuite") {}
public MathTest(string name) : base(name) {}
protected override void SetUp() {}
protected override void TearDown() {}
public static ITest Suite {
get {=20
return new TestSuite(typeof(MathTest));=20
}
}
static double x =3D 0.1234;
static double y =3D 12.345;
public void TestDecimalAbs() {
decimal a =3D -9.0M;
Assert(9.0M =3D=3D Math.Abs(a));
}
public void TestDoubleAbs() {
double a =3D -9.0D;
Assert(9.0D =3D=3D Math.Abs(a));
}
public void TestFloatAbs() {
float a =3D -9.0F;
Assert(9.0F =3D=3D Math.Abs(a));
}
public void TestLongAbs() {
long a =3D -9L;
long b =3D Int64.MinValue;
Assert(9L =3D=3D Math.Abs(a));
try {
Math.Abs(b);
Fail("Should raise System.OverflowException");
} catch(Exception e) {
Assert(typeof(OverflowException) =3D=3D e.GetType());
}
}
public void TestIntAbs() {
int a =3D -9;
int b =3D Int32.MinValue;
Assert(9 =3D=3D Math.Abs(a));
try {
Math.Abs(b);
Fail("Should raise System.OverflowException");
} catch(Exception e) {
Assert(typeof(OverflowException) =3D=3D e.GetType());
}
}
public void TestSbyteAbs() {
sbyte a =3D -9;
sbyte b =3D SByte.MinValue;
Assert(9 =3D=3D Math.Abs(a));
try {
Math.Abs(b);
Fail("Should raise System.OverflowException");
} catch(Exception e) {
Assert(typeof(OverflowException) =3D=3D e.GetType());
}
}
public void TestShortAbs() {
short a =3D -9;
short b =3D Int16.MinValue;
Assert(9 =3D=3D Math.Abs(a));
try {
Math.Abs(b);
Fail("Should raise System.OverflowException");
} catch(Exception e) {
Assert(typeof(OverflowException) =3D=3D e.GetType());
}
}
public void TestAcos() {
double a =3D Math.Acos(x);
double b =3D 1.4470809809523457;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Acos(-1.01D)));
Assert(double.IsNaN(Math.Acos(1.01D)));
}
public void TestAsin() {
double a =3D Math.Asin(x);
double b =3D 0.12371534584255098;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Asin(-1.01D)));
Assert(double.IsNaN(Math.Asin(1.01D)));
}
public void TestAtan() {
double a =3D Math.Atan(x);
double b =3D 0.12277930094473837;
double c =3D 1.5707963267948966;
double d =3D -1.5707963267948966;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert("should return NaN",=20
double.IsNaN(Math.Atan(double.NaN)));
Assert(Math.Atan(double.PositiveInfinity).ToString("G99")+" !=3D =
"+c.ToString("G99"),=20
Math.Abs((double)Math.Atan(double.PositiveInfinity) - c) <=3D =
double.Epsilon);
Assert(Math.Atan(double.NegativeInfinity).ToString("G99")+" !=3D =
"+d.ToString("G99"),
Math.Abs((double)Math.Atan(double.NegativeInfinity) - d) <=3D =
double.Epsilon);
}
public void TestAtan2() {
double a =3D Math.Atan2(x, y);
double b =3D 0.0099956168687207747;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Acos(-2D)));
Assert(double.IsNaN(Math.Acos(2D)));
}
public void TestCos() {
double a =3D Math.Cos(x);
double b =3D 0.99239587670489104;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
}
public void TestCosh() {
double a =3D Math.Cosh(x);
double b =3D 1.0076234465130722;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(Math.Cosh(double.NegativeInfinity) =3D=3D =
double.PositiveInfinity);
Assert(Math.Cosh(double.PositiveInfinity) =3D=3D =
double.PositiveInfinity);
Assert(double.IsNaN(Math.Cosh(double.NaN)));
}
public void TestSin() {
double a =3D Math.Sin(x);
double b =3D 0.12308705821137626;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
}
public void TestSinh() {
double a =3D Math.Sinh(x);
double b =3D 0.12371341868561381;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
}
public void TestTan() {
double a =3D Math.Tan(x);
double b =3D 0.12403019913793806;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
}
public void TestTanh() {
double a =3D Math.Tanh(x);
double b =3D 0.12277743150353424;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
}
public void TestSqrt() {
double a =3D Math.Sqrt(x);
double b =3D 0.35128336140500593;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
}
public void TestExp() {
double a =3D Math.Exp(x);
double b =3D 1.1313368651986859;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Exp(double.NaN)));
Assert(Math.Exp(double.NegativeInfinity) =3D=3D 0);
Assert(Math.Exp(double.PositiveInfinity) =3D=3D =
double.PositiveInfinity);
}
public void TestCeiling() {
double a =3D Math.Ceiling(1.5);
double b =3D 2;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(Math.Ceiling(double.NegativeInfinity) =3D=3D =
double.NegativeInfinity);
Assert(Math.Ceiling(double.PositiveInfinity) =3D=3D =
double.PositiveInfinity);
Assert(double.IsNaN(Math.Ceiling(double.NaN)));
}
public void TestFloor() {
double a =3D Math.Floor(1.5);
double b =3D 1;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(Math.Floor(double.NegativeInfinity) =3D=3D =
double.NegativeInfinity);
Assert(Math.Floor(double.PositiveInfinity) =3D=3D =
double.PositiveInfinity);
Assert(double.IsNaN(Math.Floor(double.NaN)));
}
public void TestIEEERemainder() {
double a =3D Math.IEEERemainder(y, x);
double b =3D 0.0050000000000007816;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.IEEERemainder(y, 0)));
}
public void TestLog() {
double a =3D Math.Log(y);
double b =3D 2.513251122797143;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Log(-1)));
Assert(double.IsNaN(Math.Log(double.NaN)));
// MS docs say this should be PositiveInfinity
Assert(Math.Log(0) =3D=3D double.NegativeInfinity);
Assert(Math.Log(double.PositiveInfinity) =3D=3D =
double.PositiveInfinity);
}
public void TestLog2() {
double a =3D Math.Log(x, y);
double b =3D -0.83251695325303621;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Log(-1, y)));
Assert(double.IsNaN(Math.Log(double.NaN, y)));
Assert(double.IsNaN(Math.Log(x, double.NaN)));
Assert(double.IsNaN(Math.Log(double.NegativeInfinity, y)));
Assert(double.IsNaN(Math.Log(x, double.NegativeInfinity)));
Assert(double.IsNaN(Math.Log(double.PositiveInfinity, =
double.PositiveInfinity)));
// MS docs say this should be PositiveInfinity
Assert(Math.Log(0, y) =3D=3D double.NegativeInfinity);
Assert(Math.Log(double.PositiveInfinity, y) =3D=3D =
double.PositiveInfinity);
Assert(Math.Log(x, double.PositiveInfinity) =3D=3D 0);
}
public void TestLog10() {
double a =3D Math.Log10(x);
double b =3D -0.90868484030277719;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Log10(-1)));
Assert(double.IsNaN(Math.Log10(double.NaN)));
// MS docs say this should be PositiveInfinity
Assert(Math.Log10(0) =3D=3D double.NegativeInfinity);
Assert(Math.Log10(double.PositiveInfinity) =3D=3D =
double.PositiveInfinity);
}=09
public void TestPow() {
double a =3D Math.Pow(y, x);
double b =3D 1.363609446060212;
Assert(a.ToString("G99") + " !=3D " + b.ToString("G99"),=20
(Math.Abs(a - b) <=3D double.Epsilon));
Assert(double.IsNaN(Math.Pow(y, double.NaN)));
Assert(double.IsNaN(Math.Pow(double.NaN, x)));
Assert(Math.Pow(double.NegativeInfinity, 1) =3D=3D =
double.NegativeInfinity);
Assert(Math.Pow(double.NegativeInfinity, 2) =3D=3D =
double.PositiveInfinity);
// MS docs say this should be 0
Assert(double.IsNaN(Math.Pow(1, double.NegativeInfinity)));
Assert(Math.Pow(double.PositiveInfinity, double.NegativeInfinity) =
=3D=3D 0);
Assert(Math.Pow(double.PositiveInfinity, 1) =3D=3D =
double.PositiveInfinity);
// MS docs say this should be PositiveInfinity
Assert(double.IsNaN(Math.Pow(1, double.PositiveInfinity)));
}=09
public void TestByteMax() {
byte a =3D 1;
byte b =3D 2;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestDecimalMax() {
decimal a =3D 1.5M;
decimal b =3D 2.5M;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestDoubleMax() {
double a =3D 1.5D;
double b =3D 2.5D;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestFloatMax() {
float a =3D 1.5F;
float b =3D 2.5F;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestIntMax() {
int a =3D 1;
int b =3D 2;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestLongMax() {
long a =3D 1L;
long b =3D 2L;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestSbyteMax() {
sbyte a =3D 1;
sbyte b =3D 2;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestShortMax() {
short a =3D 1;
short b =3D 2;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestUintMax() {
uint a =3D 1U;
uint b =3D 2U;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestUlongMax() {
ulong a =3D 1UL;
ulong b =3D 2UL;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestUshortMax() {
ushort a =3D 1;
ushort b =3D 2;
Assert(b =3D=3D Math.Max(a, b));
Assert(b =3D=3D Math.Max(b, a));
}
public void TestByteMin() {
byte a =3D 1;
byte b =3D 2;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestDecimalMin() {
decimal a =3D 1.5M;
decimal b =3D 2.5M;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestDoubleMin() {
double a =3D 1.5D;
double b =3D 2.5D;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestFloatMin() {
float a =3D 1.5F;
float b =3D 2.5F;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestIntMin() {
int a =3D 1;
int b =3D 2;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestLongMin() {
long a =3D 1L;
long b =3D 2L;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestSbyteMin() {
sbyte a =3D 1;
sbyte b =3D 2;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestShortMin() {
short a =3D 1;
short b =3D 2;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestUintMin() {
uint a =3D 1U;
uint b =3D 2U;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestUlongMin() {
ulong a =3D 1UL;
ulong b =3D 2UL;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestUshortMin() {
ushort a =3D 1;
ushort b =3D 2;
Assert(a =3D=3D Math.Min(a, b));
Assert(a =3D=3D Math.Min(b, a));
}
public void TestDecimalRound() {
decimal a =3D 1.5M;
decimal b =3D 2.5M;
Assert(Math.Round(a) + " !=3D 2", Math.Round(a) =3D=3D 2);
Assert(Math.Round(b) + " !=3D 2", Math.Round(b) =3D=3D 2);
}
public void TestDecimalRound2() {
decimal a =3D 3.45M;
decimal b =3D 3.46M;
Assert(Math.Round(a, 1) =3D=3D 3.4M);
Assert(Math.Round(b, 1) =3D=3D 3.5M);
}
public void TestDoubleRound() {
double a =3D 1.5D;
double b =3D 2.5D;
Assert(Math.Round(a) + " !=3D 2", Math.Round(a) =3D=3D 2);
Assert(Math.Round(b) + " !=3D 2", Math.Round(b) =3D=3D 2);
}
public void TestDoubleRound2() {
double a =3D 3.45D;
double b =3D 3.46D;
Assert(Math.Round(a, 1) =3D=3D 3.4D);
Assert(Math.Round(b, 1) =3D=3D 3.5D);
}
=09
public void TestDecimalSign() {
decimal a =3D -5M;
decimal b =3D 5M;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
Assert(Math.Sign(0M) =3D=3D 0);
}
public void TestDoubleSign() {
double a =3D -5D;
double b =3D 5D;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
Assert(Math.Sign(0D) =3D=3D 0);
}
public void TestFloatSign() {
float a =3D -5F;
float b =3D 5F;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
Assert(Math.Sign(0F) =3D=3D 0);
}
public void TestIntSign() {
int a =3D -5;
int b =3D 5;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
}
public void TestLongSign() {
long a =3D -5L;
long b =3D 5L;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
Assert(Math.Sign(0L) =3D=3D 0);
}
public void TestSbyteSign() {
sbyte a =3D -5;
sbyte b =3D 5;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
Assert(Math.Sign(0) =3D=3D 0);
}
public void TestShortSign() {
short a =3D -5;
short b =3D 5;
Assert(Math.Sign(a) =3D=3D -1);
Assert(Math.Sign(b) =3D=3D 1);
Assert(Math.Sign(0) =3D=3D 0);
}
}
}
------=_NextPart_000_0000_01C1BF84.CFDF22E0--