473,387 Members | 1,493 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Math Error in the .NET Framework 1.1.4322 SP1

I have discovered a math error in the .NET framework's Log function. It
returns incorrect results for varying powers of 2 that depend on whether the
program is run from within the IDE or from the command line. The amount by
which the calculation is off is very small; even though the double data type
holds the errant value, it seems to round off when printed (via ToString())
and shows the correct one. The problem is that the errant value is still used
in further calculations, which can throw off some functions.

Specific example:

The function System.Math.Log(8,2) yields a value of 3 - 4x10^-16
(2.9999999999999996) instead of 3 when run from a command line (this will not
occur if run inside the IDE). You can store the result of this computation in
a double precision variable, but if you print the variable's value to the
console by calling its ToString() method, the output will be 3. You can
verify, however, that the value is indeed off by printing the result of some
calculations using it. To see this, use Visual Studio to create a new C#
console application and paste the following code sample in its "Main" method:

---- Begin Code Sample ---
// try log function using the overloaded method that specifies the base
Console.WriteLine("Using System.Math.Log overload to specify desired
base...");
double log = System.Math.Log(8,2); // compute the log of 8 to the
base of 2 (should be 3, but will be 3 - 4x10^-16 when run from a command
prompt – note will print out as 3 regardless)
double floor = System.Math.Floor(log); // get the floor of the result
(should be 3, but will be 2 when run from a command prompt)
Console.WriteLine("Log2 8 = " + log.ToString()); // print the log of 8 to
the base of 2
Console.WriteLine("Floor(Log2 8) = " + floor.ToString()); // print the
floor of the result
Console.WriteLine("Log2 8 == 3? : " + ((bool) (log == 3)).ToString()); //
print whether the log of 8 to the base of 2 is equal to 3 (should be true,
but will be false when run from a command prompt)

Console.WriteLine();

// try the log function while doing things the "manual" way
Console.WriteLine("Using Log x / Log y method of computing the same
logarithm...");
log = System.Math.Log(8) / System.Math.Log(2); // compute the log of 8 to
the base of 2 (will be 3)
floor = System.Math.Floor(log); // get the floor of the result (will
be 3)
Console.WriteLine("Log2 8 = " + log.ToString()); // print the log of 8 to
the base of 2 computed via Log x / Log y
Console.WriteLine("Floor(Log2 8) = " + floor.ToString()); // print the
floor of the result
Console.WriteLine("Log2 8 == 3? : " + ((bool) (log == 3)).ToString()); //
print whether the log of 8 to the base of 2 is equal to 3 (will be true)

Console.Read();
--- End Code Sample ---
Note that if you calculate via log x / log y then the calculation is
correct. Using ILDASM to examine mscorlib.dll reveals that this is what is
actually happening internally. That is, the overloaded method
System.Math.Log(double a,double newBase) actually calls
System.Math.Log(double d) and divides the result by another call to
System.Math.Log(double d). That there is a difference between the results
returned by the framework when it does this internally as opposed to when you
do it is certainly interesting.

You can see the actual value of the log function by putting a statement
such as "Console.Read()" as your first line so you have a way to get the
program to stop. Compile the program and run it from the command line. Open a
new instance of Visual Studio and click on Tools > Debug Processes and select
the application. Once you have attached the debugger, break the application
and start stepping through the code. Add the variable "log" to your watch
window and you will see its value is 3 - 4x10^-16, not 3 when computed using
System.Math.Log(8,2). These steps must be taken, as the problem will not
occur if you initially start the program within the IDE.

Additionally, the problem can be verified with one line of code. Create a
new C# console application and run the following code:

Console.WriteLine(System.Math.Log(8,2) == 3);

which will print “true” when run from within the IDE and “false” when run
from the command line.

The interesting thing here is that the issue occurs on some powers of 2 if
the program is run from the command line and different powers of two if run
from within the IDE. I have verified this by computing the first 64
logarithms of 2 from both IDE and command line. You can do so by running the
following code:

for(int pow = 1;pow <= 64;pow++)
{
if(System.Math.Log(System.Math.Pow(2,pow),2) != pow)
Console.WriteLine(pow.ToString());
}

Additionally, you can compute the same logarithms in VB.NET and the answers
will still be off. This rules out the problem being isolated to a single
language and shows the issue is within the framework itself. As an
interesting side check, I computed these logarithms from VB 6.0 and all
passed the test, so the problem is isolated to .NET.

Lastly, computation using log x / log y is also off, but for different
powers of 2 than what log(power,newBase) is and it is more consistent; it
computes the incorrect value for the same powers when run from either the
command line or the IDE.

I contacted Microsoft support regarding this and they verified that they
have reproduced the problem. The last correspondence with them said, “[I am]
creating a problem report to send to the dev team now”.

The most concerning thing about all of this is that programs, at least in
this instance, behave differently when run from the command line than they do
when run inside the IDE. I find the fact that the value of calculations is
different depending on how you start your application to be alarming.
Jul 21 '05 #1
1 2686
Hi

Your problem is the way .NET processes the ==

Try this

double x = 8;
double y = 2;
double log = System.Math.Log(x,y);

if( Convert.ToDecimal(log) == Convert.ToDecimal(3) )
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
/// Output is true
Daniel Roth
MCSD.NET

limelight <li*******@discussions.microsoft.com> wrote in message news:<A4**********************************@microso ft.com>...
I have discovered a math error in the .NET framework's Log function. It
returns incorrect results for varying powers of 2 that depend on whether the
program is run from within the IDE or from the command line. The amount by
which the calculation is off is very small; even though the double data type
holds the errant value, it seems to round off when printed (via ToString())
and shows the correct one. The problem is that the errant value is still used
in further calculations, which can throw off some functions.

Specific example:

The function System.Math.Log(8,2) yields a value of 3 - 4x10^-16
(2.9999999999999996) instead of 3 when run from a command line (this will not
occur if run inside the IDE). You can store the result of this computation in
a double precision variable, but if you print the variable's value to the
console by calling its ToString() method, the output will be 3. You can
verify, however, that the value is indeed off by printing the result of some
calculations using it. To see this, use Visual Studio to create a new C#
console application and paste the following code sample in its "Main" method:

---- Begin Code Sample ---
// try log function using the overloaded method that specifies the base
Console.WriteLine("Using System.Math.Log overload to specify desired
base...");
double log = System.Math.Log(8,2); // compute the log of 8 to the
base of 2 (should be 3, but will be 3 - 4x10^-16 when run from a command
prompt – note will print out as 3 regardless)
double floor = System.Math.Floor(log); // get the floor of the result
(should be 3, but will be 2 when run from a command prompt)
Console.WriteLine("Log2 8 = " + log.ToString()); // print the log of 8 to
the base of 2
Console.WriteLine("Floor(Log2 8) = " + floor.ToString()); // print the
floor of the result
Console.WriteLine("Log2 8 == 3? : " + ((bool) (log == 3)).ToString()); //
print whether the log of 8 to the base of 2 is equal to 3 (should be true,
but will be false when run from a command prompt)

Console.WriteLine();

// try the log function while doing things the "manual" way
Console.WriteLine("Using Log x / Log y method of computing the same
logarithm...");
log = System.Math.Log(8) / System.Math.Log(2); // compute the log of 8 to
the base of 2 (will be 3)
floor = System.Math.Floor(log); // get the floor of the result (will
be 3)
Console.WriteLine("Log2 8 = " + log.ToString()); // print the log of 8 to
the base of 2 computed via Log x / Log y
Console.WriteLine("Floor(Log2 8) = " + floor.ToString()); // print the
floor of the result
Console.WriteLine("Log2 8 == 3? : " + ((bool) (log == 3)).ToString()); //
print whether the log of 8 to the base of 2 is equal to 3 (will be true)

Console.Read();
--- End Code Sample ---
Note that if you calculate via log x / log y then the calculation is
correct. Using ILDASM to examine mscorlib.dll reveals that this is what is
actually happening internally. That is, the overloaded method
System.Math.Log(double a,double newBase) actually calls
System.Math.Log(double d) and divides the result by another call to
System.Math.Log(double d). That there is a difference between the results
returned by the framework when it does this internally as opposed to when you
do it is certainly interesting.

You can see the actual value of the log function by putting a statement
such as "Console.Read()" as your first line so you have a way to get the
program to stop. Compile the program and run it from the command line. Open a
new instance of Visual Studio and click on Tools > Debug Processes and select
the application. Once you have attached the debugger, break the application
and start stepping through the code. Add the variable "log" to your watch
window and you will see its value is 3 - 4x10^-16, not 3 when computed using
System.Math.Log(8,2). These steps must be taken, as the problem will not
occur if you initially start the program within the IDE.

Additionally, the problem can be verified with one line of code. Create a
new C# console application and run the following code:

Console.WriteLine(System.Math.Log(8,2) == 3);

which will print â€Å"true” when run from within the IDE and â€Å"false” when run
from the command line.

The interesting thing here is that the issue occurs on some powers of 2 if
the program is run from the command line and different powers of two if run
from within the IDE. I have verified this by computing the first 64
logarithms of 2 from both IDE and command line. You can do so by running the
following code:

for(int pow = 1;pow <= 64;pow++)
{
if(System.Math.Log(System.Math.Pow(2,pow),2) != pow)
Console.WriteLine(pow.ToString());
}

Additionally, you can compute the same logarithms in VB.NET and the answers
will still be off. This rules out the problem being isolated to a single
language and shows the issue is within the framework itself. As an
interesting side check, I computed these logarithms from VB 6.0 and all
passed the test, so the problem is isolated to .NET.

Lastly, computation using log x / log y is also off, but for different
powers of 2 than what log(power,newBase) is and it is more consistent; it
computes the incorrect value for the same powers when run from either the
command line or the IDE.

I contacted Microsoft support regarding this and they verified that they
have reproduced the problem. The last correspondence with them said, â€Å"[I am]
creating a problem report to send to the dev team now”.

The most concerning thing about all of this is that programs, at least in
this instance, behave differently when run from the command line than they do
when run inside the IDE. I find the fact that the value of calculations is
different depending on how you start your application to be alarming.

Jul 21 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Joachim | last post by:
I made some project changes (which seems it doesn't help if I undo) which have created compilation error: " Server Error in '/PCSWebApp1' Application....
1
by: Invalidlastname | last post by:
Hi, Our developer team recently started getting the compilation error, see below, once a while running the asp.net web application from Visual Studio 2003 (in debug mode), and we have to rebuild the...
5
by: Raterus | last post by:
I'm just throwing this error out for my sanity, I've seen posts about this, but never solutions. I'm using VS.NET 2003, Framework 1.1, and I'm getting a random error about every 1 out of 10 times...
9
by: JTrigger | last post by:
When I compile my project using the IDE on a development machine it works just fine. When I compile it on the server using csc.exe, I get the following error when I try to bring it up in the web...
0
by: Jie | last post by:
Does anyone know why I keep having the following error. I have to rebuild the solution every time I run it in design mode. thanks jie Server Error in '/ReapPortal' Application....
2
by: Kevin R. | last post by:
I have been ignoring this problem for a few weeks now, but it's becoming a bit annoying not to mention unproductive. Here it goes: I compile my project with no errors. Then after I debug/run it,...
4
by: james margey | last post by:
Hi to all, I have spent 3 days at this error and i have two days to go for a deadline, and i am about to go off my nut, the reason being: Microsoft dont seem to be able to provide a solution, I...
1
by: abh1508 | last post by:
Following a release of code the following problem occurs on certain asp ..net pages. This is not a problem on other testing/demo environments. IIS seems to be creating certain files twice in the...
1
by: limelight | last post by:
I have discovered a math error in the .NET framework's Log function. It returns incorrect results for varying powers of 2 that depend on whether the program is run from within the IDE or from the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.