I have made a calculator with C# (in VS 2008), but I can't understand why the
checked{iCurrent = (iCurrent * 10) + i;}
can check the overflow, can someone explain this? Thanks.
This is my code:
try
{
//get the typed
long iCurrent=long.Parse(textOut.Text);
if(bNumBegins)
{
iCurrent = i;
bNumBegins = false;
}
else
{
//check whether overflow
checked{iCurrent = (iCurrent * 10) + i;}
}
textOut.Text = iCurrent.ToString();
}
When you use the checked keyword you ask the compiler to automatically generate code that will test whether overflow has occurred after arithmetic operations. If overflow is detected, an OverflowException is thrown.
The default in C# is to not check for such overflow when performing arithmetic operations. The default can be changed to check all operations. Regardless of the default, the checked and unchecked keywords can be used to selectively check or ignore overflow as needed.
#DavidPilkington Yes, why need * 10? Thanks
I think that you are confused here.
The code is multiplying the iCurrent variable by 10 and then adding one. This is the desired effect that the coder wanted. The checked keyword is used to make sure that there is no OverflowException.
The *10 is not needed for the checked, the check is "needed" for the operation to ensure that the number is not too large.
Here is the MSDN documention on checked. I suggest you read through it and the examples to gain a better understanding.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I don't know why but I am getting a FormatException when comparing two values. Could someone tell me what I am doing wrong? I already tried to make both values float, yet the same exception...
float label1 = float.Parse(label15.Text);
int box1 = int.Parse(textBox23.Text);
if (label1 <= box1)
{
//Do things"
}
FormatException
The exception that is thrown when the format of an argument is
invalid, or when a composite format string is not well formed.
the error is because whatever the value of label15 / textBox23 is, it is not a valid number.
use float.TryParse and int.TryParse respectively as they don't throw exceptions:
float label1;
if(label15.Text, out label1){
// do something
}
int box1;
if(textBox23.Text, out box1){
// do something
}
though, you'll still need to ensure that label15 / textBox23 is a parsable value, otherwise control will not go inside the if statements.
You've got yourself in a corner without using proper exception handling.
float label1 = float.Parse(label15.Text); //problem 1
int box1 = int.Parse(label15.Text); //problem 2
if (label1 <= box1) //problem 3
{
//Do things"
}
Problems 1 and 2 are that you aren't ensuring your UI is giving you values that you can parse. That will throw exceptions. Problem 3 is that since you don't know if your parsing was successful, you don't know if you can even make the comparison. Try TryParse().
float label1 = 0;
int box1 = 0;
if(float.TryParse(label15.Text, out label1)
&& int.TryParse(label15.Text, out box1))
{
if (label1 <= box1)
{
//Do things"
}
}
The TryParse() function populates your existing variables as out parameters, but returns a bool. This returns as false if the parse fails, and allows the code to continue. By making these succeeding an if condition, we sidestep errors entirely.
You can also always wrap your code in a try-catch block to determine the cause of any exception and generate output, but you never want that to manage your logical flow. You'd use that to troubleshoot this problem, and what I posted as a possible solution.
The float.Parse method can take a second parameter.
Assuming you are looking for German number parsing based on your profile.
So if you want to parse German number formats, make sure the method knows that (because by US standards, "2,5" is not a floating point number... there's not even a point to start with).
In theory, your System.Globalization.CultureInfo.CurrentCulture should already be what you need. In case it's not, you can create a culture you need:
This should work fine:
float f = float.Parse("2,5", new System.Globalization.CultureInfo("de-DE"))
Keep in mind that despite your best efforts, people might still just enter garbage in your textbox, so you should keep an eye out for TryParse as mentioned in the other answers. But even there: watch out for the correct culture to parse your numbers.
Code in C#:
address = glowObject + (glowIndex * 0x38) + 0x4;
Code in VB:
address = glowObject + (glowIndex * &H38) + &H4
I inserted a breakpoint on that line in both my C# code and VB code.
The values were the same in both.
C#: Breakpoint:
VB Breakpoint:
So it looks like my VB code is getting the result, but it's still throwing an exception on that line of code.
What could be causing this?
In C#, arithmetic operations are unchecked by default, which means that arithmetic overflow is not checked at runtime. You can control this with the checked/unchecked keywords, and/or with the /checked compiler option.
In VB.NET, arithmetic operations are checked by default.
In your code, the result overflows the capacity of an int; in C#, it overflows silently, producing an incorrect result, whereas in VB.NET, it throws an exception. In either case, your code has a bug...
Found the solution :)
It was as simple as checking a box in the compiler options.
Thank you to Thomas Levesque for telling me about the compiler option.
Go to the compile tab in your project settings, click on Advanced Compiler Settings, and check the "Remove integer overflow checks"
Hi I just ran a static code analysis on my code and I keep getting the error
"Integer Operation Without Overflow Check"
Can someone help me resolve this or tell me what it means exactly. I have already tried to using the check keywords to fix this but it still came up when I ran the code.
List<String> emailList = new List<string>();
if (tbRecipients.Text.Contains(','))
{
string[] splits = tbRecipients.Text.Split(',');
for (int i = 0; i < splits.Length; i++)
{
if (splits[i].Contains(';'))
{
emailList.AddRange(splits[i].Split(';').ToList());
}
else
{
emailList.Add(splits[i]);
}
}
}
ASPX
<asp:TextBox ID="tbRecipients" runat="server" ></asp:TextBox>
The message you get says that you could get an "overflow" on an int, that's because ints in C# are 32 bit so that you can only store in it numbers lower than 2^31. So VCG tell you that while doing several i++ you could end up with an i = 2^31 which would overflow your int and yield unexpected code behavior.
This could only happen in your code in the case that splitted.Length == int.MaxValue since splitted is an array and the Length property is int, so when you get i == int.MaxLength the loop will evaluate i == splitted.Length and will go to i++ which would overflow.
However your loop says i < splitted.Length so that i == splitted.Length won't happen.
Bottom line: I think VCG has spotted a suspicious line, but there is nothing to worry about.
Hope this helps, happy coding.
I have already tried to using the check keywords to fix this
The first step would be to understand the message. Making random code changes it not a good way to deal with possible bugs that are reported to you.
Here, there is no possible integer overflow. Hard to say more without details about the tool.
I'm currently reading through C# 4.0 In A Nutshell, and in chapter 2 it states that if an int object has a value of int.MinValue (-2147483648) and the value is decreased, as the value cannot go any lower, it goes to the highest value, int.MaxValue (2147483647):
int a = int.MinValue;
Console.WriteLine(a); //-2147483648
a = a-1;
Console.WriteLine(a); //-2147483648
Console.WriteLine (a == int.MaxValue); // True
The book then goes on to mention how you can protect from this happening using checked.
However, I'm wondering why this is possible? Surely this could cause a lot of issues if its not protected with checked?
Is it not a bit of a flaw in the design? Why would anyone want a minimum value to become a maximum value?
Furthermore, I've noticed VB.NET will throw an 'Arithmetic overflow' instead of letting this happen:
Dim a As Integer
a = Integer.MaxValue
a = a + 1
Response.Write(a) 'Arithmetic overflow exception here
Sometimes it is desired behaviour. Other times, it simply isn't necessary to deal with and check for overflows, as they slow down program execution. Take a game drawing unbound (FPS). At 1000FPS, a small 1ms extra check could have a significant affect on framerate. Other times, it may be expected execution (I've only seen one use of this to date) - it flows on from what happens in C#'s ancestor - C++ and C.
Also, please note that the default behaviour (checked or unchecked) varies between configurations and environments:
If neither checked nor unchecked is used, a constant expression uses
the default overflow checking at compile time, which is checked.
Otherwise, if the expression is non-constant, the run-time overflow
checking depends on other factors such as compiler options and
environment configuration.
Since the code you posted is non-constant (and also due to various environment variables), no checking for overflows is performed.
It is a matter of language design - why this happens has to do with the binary representation of numbers. In .NET this is done with two's complement, hence the overflow issue.
The designers of VB.NET have decided to not allow such overflow/underflow issues.
The designers of C# have decided to leave control to the programmer.
It is possible that your programm automatically check overflow: right click on project file,
select Build, than select Advanced button in right bottom corner. In the opened window check Check Arithmetical Overflow checkbutton.
Even experienced programmers write C# code like this sometimes:
double x = 2.5;
double y = 3;
if (x + 0.5 == 3) {
// this will never be executed
}
Basically, it's common knowledge that two doubles (or floats) can never be precisely equal to each other, because of the way the computer handles floating point arithmetic.
The problem is, everyone sort-of knows this, but code like this is still all over the place. It's just so easy to overlook.
Questions for you:
How have you dealt with this in your development organization?
Is this such a common thing that the compiler should be checking that we all should be screaming really loud for VS2010 to include a compile-time warning if someone is comparing two doubles/floats?
UPDATE: Folks, thanks for the comments. I want to clarify that I most certainly understand that the code above is incorrect. Yes, you never want to == compare doubles and floats. Instead, you should use epsilon-based comparison. That's obvious. The real question here is "how do you pinpoint the problem", not "how do you solve the technical issue".
Floating point values certainly can be equal to each other, and in the case you've given they always will be equal. You should almost never compare for equality using equals, but you do need to understand why - and why the example you've shown isn't appropriate.
I don't think it's something the compiler should necessarily warn about, but you may want to see whether it's something FxCop can pick up on. I can't see it in the warning list, but it may be there somewhere...
Personally I'm reasonably confident that competent developers would be able to spot this in code review, but that does rely on you having a code review in place to start with. It also relies on your developers knowing when to use double and when to use decimal, which is something I've found often isn't the case...
static int _yes = 0;
static int _no = 0;
static void Main(string[] args)
{
for (int i = 0; i < 1000000; i++)
{
double x = 1;
double y = 2;
if (y - 1 == x)
{
_yes++;
}
else
{
_no++;
}
}
Console.WriteLine("Yes: " + _yes);
Console.WriteLine("No: " + _no);
Console.Read();
}
Output
Yes: 1000000
No: 0
In our organization we have a lot of financial calculations and we don't use float and double for such tasks. We use Decimal in .NET, BigDecimal in Java and Numeric in MSSQL to escape round-off errors.
This article describes the problem: What Every CS Should Know About floating-Point Arithmetic
If FxCop or similar (as Jon suggests) doesn't work out for you a more heavy handed approach might be to take a copy of the code - replace all instances of float or double with a class you've written that's somewhat similar to System.Double, except that you overload the == operator to generate a warning!
I don't know if this is feasible in practice as I've not tried it - but let us know if you do try :-)
Mono's Gendarme is an FxCop-like tool. It has a rule called AvoidFloatingPointEqualityRule under the Correctness category. You could try it to find instances of this error in your code. I haven't used it, but it should analyse regular .net dll's. The FxCop rule with the same name was removed long ago.