473,395 Members | 1,666 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,395 software developers and data experts.

Once again Math.Log

I've found the discussion about Math.Log and the error with

Math.Log(8,2)

on Google. Unfortunatly the full thread isn't on my news server, so I
can't reply.

The problem doesn't only depend on representation of floating numbers.
When You execute

int res = (int)Math.Log(8, 2);
if (res == 3)
{
Console.WriteLine("right");
}
else
{
Console.WriteLine("false");
}

You get the output "false". My first thoughts also where to the floating
representation. But if You debug the same lines of Code, the debugger
steps to the output of "right", the result res is "3".
Does the debugger use another Math-engine?

--
Sleepless in Berlin
Wernfried
Nov 16 '05 #1
7 2581
Wernfried Schwenkner <we*************************@sesa.de> wrote:
I've found the discussion about Math.Log and the error with

Math.Log(8,2)

on Google. Unfortunatly the full thread isn't on my news server, so I
can't reply.

The problem doesn't only depend on representation of floating numbers.
When You execute

int res = (int)Math.Log(8, 2);
if (res == 3)
{
Console.WriteLine("right");
}
else
{
Console.WriteLine("false");
}

You get the output "false". My first thoughts also where to the floating
representation. But if You debug the same lines of Code, the debugger
steps to the output of "right", the result res is "3".

Does the debugger use another Math-engine?


No - it's just it's formatting something "very close to 3" as "3".

Personally I never trust the debugger for that kind of thing - nor even
the built-in ToString methods. If you want to really see *exactly* what
value is in a double, use something like my DoubleConverter class:

http://www.pobox.com/~skeet/csharp/DoubleConverter.cs

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #2
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in
news:MP************************@msnews.microsoft.c om:
Wernfried Schwenkner <we*************************@sesa.de> wrote:
I've found the discussion about Math.Log and the error with
<snip> You get the output "false". My first thoughts also where to the
floating representation. But if You debug the same lines of Code, the
debugger steps to the output of "right", the result res is "3".

Does the debugger use another Math-engine?


No - it's just it's formatting something "very close to 3" as "3".

<snip>

I think his point is that when he runs the program without debugging, res
is not 3, but with debugging res is 3, ie. the program take different
routes.

And he's exactly right:

reproduce:
1. create a new winforms project in VS.NET 2003
2. add a single button to the form, double-click to add event handler
3. type in the following code:

Int32 i = (Int32)Math.Log(8, 2);
if (i == 3)
Text = "i == 3";
else
Text = "i != 3";

4. run program with Ctrl-F5 to start without debugger, click button,
caption of window becomes i != 3, close program
5. run program with F5 to start with debugger, click button, caption of
window becomes i == 3

This means that the result of that cast, or the log operation, differs
wether you use the debugger or not. Perhaps there's some slight
differences in the debug binaries of the .net runtime ?
--
Lasse Vågsæther Karlsen
la***@vkarlsen.no
PGP KeyID: 0x0270466B
Nov 16 '05 #3
Lasse Vågsæther Karlsen <la***@vkarlsen.no> wrote:
Does the debugger use another Math-engine?
No - it's just it's formatting something "very close to 3" as "3".

<snip>

I think his point is that when he runs the program without debugging, res
is not 3, but with debugging res is 3, ie. the program take different
routes.


Ah - oops. Misread :(
And he's exactly right:

reproduce:
1. create a new winforms project in VS.NET 2003
2. add a single button to the form, double-click to add event handler
3. type in the following code:

Int32 i = (Int32)Math.Log(8, 2);
if (i == 3)
Text = "i == 3";
else
Text = "i != 3";

4. run program with Ctrl-F5 to start without debugger, click button,
caption of window becomes i != 3, close program
5. run program with F5 to start with debugger, click button, caption of
window becomes i == 3

This means that the result of that cast, or the log operation, differs
wether you use the debugger or not. Perhaps there's some slight
differences in the debug binaries of the .net runtime ?


Hmm... not sure. Certainly seems very odd.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #4
Yep, the JIT compiler works a little different for executables that have
been started in the debugger. (attaching the debugger to an already running
executable doesn't change anything). For example, it doesn't inline function
calls, so you can always step into functions.
My guess is that an inlined version of Math.Log (outside the debugger) can
keep all internal results in 80-bit FPU registers, while a non-inlined
version has to return them as 64-bit double values, which leads to different
results.

i.e. if Log is defined like this:
public static double Log(double a, double newBase)
{
return (Math.Log(a)/Math.Log(newBase));
}

If Math.Log(a) and Math.Log(newBase) are inlined, the results of the calls
may stay in FPU registers (which are 80 bit long). On the other hand, if
they are not inlined, the results have to be returned as 64-bit-doubles.
That explains the loss of precision.

Niki
"Lasse Vågsæther Karlsen" <la***@vkarlsen.no> wrote in
news:Xn*****************************@207.46.248.16 ...
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in
news:MP************************@msnews.microsoft.c om:
Wernfried Schwenkner <we*************************@sesa.de> wrote:
I've found the discussion about Math.Log and the error with
<snip> You get the output "false". My first thoughts also where to the
floating representation. But if You debug the same lines of Code, the
debugger steps to the output of "right", the result res is "3".

Does the debugger use another Math-engine?


No - it's just it's formatting something "very close to 3" as "3".

<snip>

I think his point is that when he runs the program without debugging, res
is not 3, but with debugging res is 3, ie. the program take different
routes.

And he's exactly right:

reproduce:
1. create a new winforms project in VS.NET 2003
2. add a single button to the form, double-click to add event handler
3. type in the following code:

Int32 i = (Int32)Math.Log(8, 2);
if (i == 3)
Text = "i == 3";
else
Text = "i != 3";

4. run program with Ctrl-F5 to start without debugger, click button,
caption of window becomes i != 3, close program
5. run program with F5 to start with debugger, click button, caption of
window becomes i == 3

This means that the result of that cast, or the log operation, differs
wether you use the debugger or not. Perhaps there's some slight
differences in the debug binaries of the .net runtime ?
--
Lasse Vågsæther Karlsen
la***@vkarlsen.no
PGP KeyID: 0x0270466B

Nov 16 '05 #5

"Niki Estner" <ni*********@cube.net> wrote in message
news:Od*************@tk2msftngp13.phx.gbl...
Yep, the JIT compiler works a little different for executables that have
been started in the debugger. (attaching the debugger to an already running executable doesn't change anything). For example, it doesn't inline function calls, so you can always step into functions.
My guess is that an inlined version of Math.Log (outside the debugger) can
keep all internal results in 80-bit FPU registers, while a non-inlined
version has to return them as 64-bit double values, which leads to different results.

i.e. if Log is defined like this:
public static double Log(double a, double newBase)
{
return (Math.Log(a)/Math.Log(newBase));
}

If Math.Log(a) and Math.Log(newBase) are inlined, the results of the calls
may stay in FPU registers (which are 80 bit long). On the other hand, if
they are not inlined, the results have to be returned as 64-bit-doubles.
That explains the loss of precision.
Agreed, and to back up your suppostion, from the Tool Developer's Guide,
section 11.1.3:

"Storage locations for floating point numbers (statics, array elements, and
fields of classes) are of fixed size. The supported storage sizes are
float32 and float64. Everywhere else (on the evaluation stack, as arguments,
as return types, and as local variables) floating point numbers are
represented using an internal floating-point type. In each such instance,
the nominal type of the variable or expression is either R4 or R8, but its
value may be represented internally with additional range and/or precision.
The size of the internal floating-point representation is
implementation-dependent, may vary, and shall have precision at least as
great as that of the variable or expression being represented. "

and furthermore:

"Note: The use of an internal representation that is wider than float32 or
float64 may cause differences in computational results when a developer
makes seemingly unrelated modifications to their code, the result of which
may be that a value is spilled from the internal representation (e.g. in a
register) to a location on the stack. "

Stu

Niki
"Lasse Vågsæther Karlsen" <la***@vkarlsen.no> wrote in
news:Xn*****************************@207.46.248.16 ...
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in
news:MP************************@msnews.microsoft.c om:
Wernfried Schwenkner <we*************************@sesa.de> wrote:
> I've found the discussion about Math.Log and the error with
>

<snip>
> You get the output "false". My first thoughts also where to the
> floating representation. But if You debug the same lines of Code, the
> debugger steps to the output of "right", the result res is "3".
>
> Does the debugger use another Math-engine?

No - it's just it's formatting something "very close to 3" as "3".

<snip>

I think his point is that when he runs the program without debugging, res is not 3, but with debugging res is 3, ie. the program take different
routes.

And he's exactly right:

reproduce:
1. create a new winforms project in VS.NET 2003
2. add a single button to the form, double-click to add event handler
3. type in the following code:

Int32 i = (Int32)Math.Log(8, 2);
if (i == 3)
Text = "i == 3";
else
Text = "i != 3";

4. run program with Ctrl-F5 to start without debugger, click button,
caption of window becomes i != 3, close program
5. run program with F5 to start with debugger, click button, caption of
window becomes i == 3

This means that the result of that cast, or the log operation, differs
wether you use the debugger or not. Perhaps there's some slight
differences in the debug binaries of the .net runtime ?
--
Lasse Vågsæther Karlsen
la***@vkarlsen.no
PGP KeyID: 0x0270466B


Nov 16 '05 #6
"Stu Smith" <st*****@nospam-digita.com> wrote in
news:eg*************@TK2MSFTNGP11.phx.gbl:

<snip>
"Note: The use of an internal representation that is wider than
float32 or float64 may cause differences in computational results when
a developer makes seemingly unrelated modifications to their code, the
result of which may be that a value is spilled from the internal
representation (e.g. in a register) to a location on the stack. "

<snip>

Nice explanation. It makes sense, just didn't think about this when I
looked at the original post.

I can see this as the source for future discussions like "what's the point
of using the debugger if the code behaves different" but anyone wanting to
use that point please bear in mind that the original post was about a cast
to Int32 from a double, relying on the floating point value to be exactly
like 3, and anyone that knows anything about floating point numbers knows
that the likelihood of that is 50/50, and there's only a 10% chance of
that.

:)

--
Lasse Vågsæther Karlsen
la***@vkarlsen.no
PGP KeyID: 0x0270466B
Nov 16 '05 #7
In article <Xn*****************************@207.46.248.16>,
la***@vkarlsen.no says...
I can see this as the source for future discussions like "what's the point
of using the debugger if the code behaves different" but anyone wanting to
use that point please bear in mind that the original post was about a cast
to Int32 from a double, relying on the floating point value to be exactly
like 3, and anyone that knows anything about floating point numbers knows
that the likelihood of that is 50/50, and there's only a 10% chance of
that.


No, my post was not a question relying on floating point values. I know
the floating point representaion very well (wrote floating point
routines in assembler myself without having a FPP). My problem was the
different behaviour in debug and release mode. So the answers could
clearify all.
--
Sleepless in Berlin
Wernfried
Nov 16 '05 #8

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

Similar topics

0
by: Filip Polsakiewicz | last post by:
Hi all, after I moved my website to a Windows 2003 Server I experience problems with my file upload script. It worked fine before and still works for smaller files. I changed all required...
2
by: Nicolas Evrard | last post by:
Hello, I'm puzzled by this test I made while trying to transform a page in html to plain text. Because I cannot send unicode to feed, nor str so how can I do this ? ..nicoe@smarties:~$...
32
by: Werner Partner | last post by:
I put this question already, but erhaps it "came under the wheels" because it was hidden in another thread. Nevertheless it's important for me to understand the problem and solve it. Old html...
5
by: lawrence | last post by:
How to add text to a textarea using javascript? Apparently this is a popular question, because when I run the search on google, there are a lot of returns: ...
4
by: Edward Diener | last post by:
In MC++ properties are syntactically created through member functions declared with the __property keyword and using set_ and get_ naming conventions. Given that a property is specified in this...
4
by: Hexman | last post by:
I was going along fine in my test to see how to manipulate the DataGrid (dgTrans) and its columns. I have a single form with one DataGrid (dgTrans) on it. The code I have in my form load event...
17
by: mdh | last post by:
Starting Chapter 5 in K&R, and it does not get easier..but it is worth it...I am repeatedly told! K&R say that in the statement p=&c; "p is said to "point to c". I know this will sound...
6
by: rn5a | last post by:
I had posted this query about 3 days back but having got no response yet, I am posting the same query again since I need to resolve the issue urgently. Sorry for the same... I have already lost...
7
by: Szabolcs Borsanyi | last post by:
I know that this topic has been discussed a lot, still I'd appreciate a clear cut (and correct) answer: I pass a multidimensional array to a function, which is defined as int f(int a) { int...
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: 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...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.