John, Are you familiar with the inherent inexactness of floating-point (FP) operations? If not then I would recommend that you first read Bruce M. Bush's highly informative paper "The Perils of Floating Point" at the Lahey website: http://www.lahey.com/float.htm
Briefly, FP operations may not give the expected result (e.g. 3.0) but some other result in the vicinity (e.g. 2.999...), and that's probably what happened in your case. The output functions of WriteLine and the debugger were apparently clever enough to provide enough rounding so that a seemingly exact value was output, but the int cast simply cut off the .9999 sequence and gave 2.0 as the result. To see the actual representation of an FP value, instead of the rounded one produced by most print functions, use the "round-trip" format specifier likes this: Console.WriteLine("Log2(8) = {0:r}", Math.Log(8,2)); This command prints 2.9999999999999996 (15 times 9) which an int cast would correctly round to 2. This is with .NET SP2, by the way. That said, there does seem to be a .NET-specific problem here. A similar test program written in C and compiled into native code by MS VC++ .NET gives 3.0 as the result of log(8.0)/log(2.0). There are only zeroes after the decimal point as far as the eye can see (I tried 30 digits; the double type is only guaranteed to have 15 digits of precision), and casting to int also yields 3 and not 2. So either the Math.Log algorithm is less exact than the log function of the C library, or the C compiler is clever enough to do some slight rounding of its own as required -- after all, the 6 in the .NET result above came after 16 other digits and hence was past the guaranteed precision of the System.Double type (same as double: 15 digits). Microsoft definitely should look into this. In the meantime, you should either use Math.Round before casting to int, or use Convert.ToInt32 which rounds & casts in one step. However, both methods will apply the bizarre "banker's rounding", i.e. rounding to even, which Microsoft inflicted upon us for unknown reasons. If you want real rounding you have to write it yourself: double d = Math.Log(8, 2); int i = (int) (d > 0.0 ? d + 0.5 : d - 0.5); The second line will round any FP value d to the nearest int. The comparison to zero is required in the general case, though not in this example. Cheers, Christoph At 10:31 25.08.2002 -0700, you wrote: >Given the following simple program: >using System; >public class RoundingError { > public static void Main(string[] args) { > Console.WriteLine("Log2(8) = {0}", (int) Math.Log(8,2)); > } >} > >The output is 2 if you run it standalone, but 3 (the expected value) if run >from within the Visual Studio.NET debugger. If you print the double version >of the return value, it is 3 in both cases... > >Any ideas what could be going on? I have not tried applying SP1. > >Thanks, >John > >You can read messages from the Advanced DOTNET archive, unsubscribe from >Advanced DOTNET, or >subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.