I'm using C# with the XNA library and I'm getting NaNs cropping up in my Vector3 objects. Is there a way to break into the debugger when the offending calculation happens (e.g. a divide by zero)? Currently the program just continues running. I'm using VS2008 Professional. All the exceptions in the Exceptions dialog are selected in the "user-unhandled" column.
Edit: To clarify, I can't work out where the bad calculation is. This is why I want the debugger to break automatically. Setting breakpoints is not a solution.
Firstly dividing a double/float by zero gives Infinity/-Infinity depending upon whether the double is positive or negative. Only a zero double/float divided by zero gives NaN. In either case, no exception will be thrown.
You should be able to use conditional breakpoints to detect when a particular variable gets set to one of these values. Be careful when checking for NaN though, as NaN != NaN.
double a = double.NaN;
Console.Out.WriteLine(a == double.NaN); // false
Console.Out.WriteLine(a == a); // false
Console.Out.WriteLine(double.IsNaN(a)); // true
Sounds like you're handling the exception somehow (like a catching a generic Exception) What you can do is press Ctrl+alt+E to bring up the exceptions dialog -- make sure you check the "when thrown" checkbox for the exception(s) you're interested in
You could set a conditional breakpoint that only breaks when the divisor of an expression is 0.
I know this is an old post but.....
from experience its nearly always Vector3.Normalize that i use by mistake.
When I'm not sure whether it will be zero length I now always do
float L = V.Length();
if(L != 0.0)
V /= L;
divide by zero in Normalize should give an exception but it doesn't. Caused me a lot of head scratching.
Related
I am working on a calculation module using C#, and I bumped on this :
double v = 4 / 100;
I know this is a wrong initialization that returns v = 0.0 instead of v = 0.04
The c# rules says I must ensure at least one of the member is a double, like this :
double v = (double) 4 / 100;
double v = 4.0 / 100;
However, I have many many initializations of that kind that involves integer variables operations, and I feel lazy to browse my code line by line to detect such mistakes.
Instead, is it possible to get warned by the compiler about this ?
Alright, after some playing around and what not, I have a solution. I used this article to come to this solution.I use StyleCop, so you'll need to get and install that. Then, you can download my C# project MathematicsAnalyzer.
First off, I did not account for all type conversion mismatches. In fact, I only accommodate one part.
Basically, I check to see if the line contains "double" followed by a space. I do know that could lead to false warnings, because the end of a class could be double or any number of other things, but I'll leave that to you to figure out how to properly isolate the type.
If a match is found, I check to see that it matches this regex:
double[ ][A-Za-z0-9]*[ ]?=(([ ]?[0-9]*d[ ]?/[ ]?[0-9]*;)|[ ]?[0-9]*[ ]?/[ ]?[0-9]*d;)
If it does -not- match this regex, then I add a violation. What this regex will match on is any of the following:
double i=4d / 100;
double i = 4d / 100;
double i = 4 / 100d;
double i = 4/ 100d;
double i = 4 /100d;
double i = 4/100d;
double i=4d / 100;
double i=4 / 100d;
double i=4/100d;
Any of the above will not create a violation. As it is currently written, pretty much if a 'd' isn't used, it'll throw a violation. You'll need to add extra logic to account for the other possible ways of explicitly casting an operand. As I'm writing this, I've just realized that having a 'd' on both operands will most likely throw an exception. Whoops.
And lastly, I could not get StyleCop to display my violation properly. It kept giving me an error about the rule not existing, and even with a second pair of eyes on it, we could not find a solution, so I hacked it. The error shows the name of the rule you were trying to find, so I just put the name of the rule as something descriptive and included the line number in it.
To install the custom rule, build the MathematicalAnalyzer project. Close Visual Studio and copy the DLL into the StyleCop install directory. When you open Visual Studio, you should see the rule in the StyleCop settings. Step 5 and 6 of the article I used shows where to do that.
This only gets one violation at a time throughout the solution, so you'll have to fix the violation it shows, and run StyleCop again to find the next one. There may be a way around that, but I ran out of juice and stopped here.
Enjoy!
This article explains how to set up custom Code Analysis rules that, when you run Code Analysis, can show warnings and what not.
http://blog.tatham.oddie.com.au/2010/01/06/custom-code-analysis-rules-in-vs2010-and-how-to-make-them-run-in-fxcop-and-vs2008-too/
ScrollViewer.ChangeView doesn't always work. When it doesn't - it returns false (MSDN).
What are the conditions for that happening?
EDIT
Most methods either work or throw an exception. This one has a return value. This means there are conditions where it fails (and returns false). What are those conditions?
EDIT 2 (after awarding the bounty)
I awarded the bounty so as not to waste the reputation points. I'm still looking for THE answer. (Also, the answer was written before my edit to the question.)
The return value of ScrollViewer.ChangeView signals whether the view changes (true) or not (false).
The most obvious reason why the view may not change after a ChangeView call is because it was already displaying the requested horizontal and/or vertical offsets and/or zoom factor before the call.
I have a strange behavior of a "Point"-object.
I use a Drag'n'Drop and on the drop I catch the DragEventArgs as the simple variable 'e'. Later I call this line:
Point mc = e.GetPosition(ShelfGrid);
And that leads to a nearly correct result. The mc.X is always .0, if 3.0 or 287.0 or 699.0, but the mc.Y is always .12. So the results from the mc.X taken would seem like 3.12, 287.12 and 699.12.
Now my question: "Why?"
There has to be a reason for the .12, hasn't it?
I guess, that's the Y position of your debugging code line. Having different X values means you scroll the debug code line up and down. Just write the point values to output window instead of debug points and see.
I want my program to throw an exception when some floating point variable reaches infinity or is Nan NotFiniteNumberException which looks like a solution but there is a problem.
This
try
{
Single x = 5;
x = x / 0;
x = x + 1;
}
catch (NotFiniteNumberException ex)
{
//bla bla bla
}
won't throw anything.
I'm aware of IsNan and IsInfinity methods but that's not what I'm looking for.
That's because your division won't throw a NotFiniteNumberException. It will simply return infinity for x.
From the documentation of NotFiniteNumberException:
NotFiniteNumberException is available for programming languages that do not support the concepts of infinity and Not-a-Number in floating-point operations.
C# does support infinity and Not-a-Number for floating-point operations, so this exception does not apply here. You need to manually check the value of x after performing the division.
The NotFiniteNumberException is only there as support for languages which do not natively support infinity. C# will never throw this exception. See here for one example.
As a side note, if you want to get an exception for reaching inf or nan, see my answer with code example here:
How do I force the C# compiler to throw an exception when any math operation produces 'NaN'?
There, only exceptions for NaN are set, but feel free to look into Visual Studio's version of float.h for other flags, and here: http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.html#x86_FP for an example on how to set them.
You will not get a NotFiniteNumberException-exception, though, but rather a System.ArithmeticException (tested on VS 2012).
Ehhh,
x = x / 0;
will cause a "DivisionByZeroException", so you're not gonna catch much here.
I had this weird experience with problem number 10 on Project Euler (great site by the way). The assignment was to calculate the sum of all the prime numbers below two million.
I used an int for the sum, and my algorith produced an answer, but when i pasted it to verify the answer, it was wrong.
It turned out that the result was too big to fit in an int, but wouldn't this cause an overflow error or something? Instead, it just returned a value far off from the real answer.
When I changed the type to long, everything was hunky dory.
C# integer operations don’t throw exceptions upon overflow by default. You can achieve that via the project settings, or by making the calculation checked:
int result = checked(largeInt + otherLargeInt);
Now the operation will throw.
The opposite is unchecked, which makes any operation explicitly unchecked. Obviously, this only makes sense when you’ve got checked operations enabled in the project settings.
In C# an OverflowException is not thrown (in VB the exception is thrown per default).
To get the excpetion you have to embed your code in a checked context:
byte value = 241;
checked
{
try
{
sbyte newValue = (sbyte) value;
Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
value.GetType().Name, value,
newValue.GetType().Name, newValue);
}
catch (OverflowException)
{
Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue);
}
}
MSDN explains in more detail:
For the arithmetic, casting, or
conversion operation to throw an
OverflowException, the operation must
occur in a checked context. By
default, arithmetic operations and
overflows in Visual Basic are checked;
in C#, they are not. If the operation
occurs in an unchecked context, the
result is truncated by discarding any
high-order bits that do not fit into
the destination type.
It's because, by default C# do not throw any exception for integer overflow as well as underflow. There are couple of things you can do here.
Option 1
You have to enable the exception to be thrown by go to
Project => properties => Build tab => Advanced => check for arithmetic overflow underflow.(make sure you tick the option)
Make sure you tick the option
Option 2
Use a checked block and throw an overflow exception to handle the situation. A sample code snippet would be
try
{
checked
{
int y = 1000000000;
short x = (short)y;
}
}
catch (OverflowException ex)
{
MessageBox.Show("Overflow");
}
catch (Exception ex)
{
MessageBox.Show("Error");
}
I have already added a comment, but maybe it would be interesting for some of you:
msdn tells us:
Integer arithmetic overflow either
throws an OverflowException or
discards the most significant bits of
the result
but
Decimal arithmetic overflow always
throws an OverflowException.
also
When integer overflow occurs, what
happens depends on the execution
context, which can be checked or
unchecked. In a checked context, an
OverflowException is thrown. In an
unchecked context, the most
significant bits of the result are
discarded and execution continues.
Thus, C# gives you the choice of
handling or ignoring overflow.
By default, C# does not check for arithmetic overflow on integers. You can change this with the /checked compiler option or by enabling "Check for arithmetic overflow/underflow" in Visual Studio (project properties - Build - Advanced).
You can use checked and unchecked keywords to override the default on a case-by-case basis. If you rely on checking taking place in a piece of code, explicitly enabling it using checked would be a good idea.
int j = checked(i * 2);
checked
{
int j = i * 2;
// Do more stuff
}
Note that floating point operations never throw an OverflowException, and decimal operations always throw an OverflowException. See also C# operators.
You can set checked directly in csproj by adding:
<PropertyGroup>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
</PropertyGroup>
It's the equivalent of ticking that Check for arithmetic overflow/underflow checkbox in the designer.