In debugging mode this line of code double divided by int result in an System.Overflow exception. The value for the int32 was too small/large.
The result of 0.0d/0 is NaN. Which does not fit into a int obviously.
int result = Convert.ToInt32(0.0d/0);
But how do I handle that scenario correctly that no exception happens? Or should I try catch it?
The byte size of an int is too small to fit all possible double values. See Data Types. Your best option is to carry out the conversion in a try-block and catch the OverflowException.
try
{
int result = Convert.ToInt32(0.0d/0);
}
catch (OverflowException)
{
//...
}
I'd say that depends entirely on your applications expectations.
If you know the double can be NaN or just larger than Int32.MaxValue and you like the function to continue with a specific result, you should write a check.
If an overflow is an actual exception that needs to be handled up-stack by some special logic, you should throw an exception.
You know what this calculation is supposed to calculate, so you should be already able to decide if 'NaN' is OK and what should be put into that int when such result occurs. You may catch it. You may add ifs to make sure it doesnt happen. You may leave it. You may do whatever you need, but first, you need to decide what you want to occur when a 0.0 happens. It is there for some reason.
Seeing 0.0/0.0 usually mean an error earlier in the code. 0/0 almost never makes sense, hence Not-a-Number is the result to remind about it.
In general, you may want to trace and diagnose why the division-by-zero occurred. Check why the second variable is zero (why was that /0.0 and not i.e. /1.0 ?), decide if it is a valid possible value and if it is not OK then fix the code responsible for that zero, so zero won't occur at all.
For instance, if you had a formula forcepower(x,z) / distance(x,z) and both the power and the distance turned out to be zeros because x and z were the same point, then you may add an if checking x==z and force the result to be 0.0 in such case. But, if that formula calculated foobarized whachamacallit then you should pick the most frublastic number. I don't know. You should.
---edit
Ok, after your comments I understand it now. So you've got control over all values that are used in division - good!
Since you already test 'bar' for zero and in this case force 'foo' to zero (I've seen your comment about 'because nothing can be calculated then') then the problem is in fact in the way you have designed, or, 'encoded' the results.
Forcing something to 0.0 or 0 isn't a really good way of indicating that "nothing was calculated". In later parts of the code you will have a hard time telling if the bazz is 0 because it was the result, or because it was not calculated.
Sure, of course, if 0 is an actually invalid value that normally can never occur, then its sometimes ok to use it as a special "nothing"-indicating value..
..but as you saw from that 0/0 case, it can cause inobvious problems, and also it will force you to remember to check in every place if 'values are good':
double foo;
if(bar != 0) foo = calculate_the_foo(); // check the Bar maybe it's zero
else foo = 0.0; // can't calculate, no foo
double z;
if(bar != 0) z = foo/bar; // added a check against zero in bar again..
else z = ...um? what to use here.. 0 again?
int result = Convert.ToInt32(z);
// later in the code
if(result != 0) //..again? but.. is it result of 0 or no result?
..
// and so on
It is very easy to forget to check for special values and to simply write result = foo/bar and get Infinites, NaNs or Overflows.
Therefore, it is much better to use a 0 to really mean normal zero and to use a proper no-value thing for indicating a missing data..
..and the simplest one is plain old ... null.
If you use nullables like int? or double?, then you can simply write things like:
using System.IO;
using System;
class Program
{
static void Main()
{
double? foo = 5.0;
double? bar = 4.0;
double? result = foo/bar;
Console.WriteLine("x/y: " + prettynulls(result));
// ^writes: 1.25
foo = null;
bar = 4.0;
result = foo/bar;
Console.WriteLine("null/y: " + prettynulls(result));
// ^writes: (null)
foo = 5.0;
bar = null;
result = foo/bar;
Console.WriteLine("x/null: " + prettynulls(result));
// ^writes: (null)
foo = null;
bar = null;
result = foo/bar;
Console.WriteLine("null/null: " + prettynulls(result));
// ^writes: (null)
}
private static string prettynulls(double? val)
{
return val == null ? "(null)" : val.ToString();
}
}
Please observe that you can even do operations like +-/* on them without tons of ifs to check for nulls. Mathematic operations simply will return null if one operand was null. Hence your case would become:
double? foo;
if( ... ) foo = calculate_the_foo();
else foo = null;
int? result = (int?)( foo/bar );
of by making the calculate smart with nullables when foo can't be calculated:
double? foo = calculate_the_foo();
int? result = (int?)( foo/bar );
Look at the simplicity and expressiveness. Nullables like double? even handle casting. A double? that holds a null, when casted to int? will simply be return null. Otherwise it will cast the double value to int and return int.
Related
I have simple GUI a program where the real time plot(using WinForms chart) crashes due to non-double values like infinity or NaN.
So I want to filter values such as infinity,NaN or ect. And only plot valid double values. It can also be any other non-double type.
I try the following:
if(!double.IsInfinity(value)){
chart1.Series["mySerie"].Points.AddY(value);
}
But the above only checks if the value is not infinity not other non-double possibilities.
In my case Double. TryParse also would not work because it is used to check whether text is a double.
So in my case I receive data from a device normally a double. But sometimes it outputs non-double values and is there a quick fix for it?
To illustrate my comment with a range of acceptable values:
using System;
public class Program
{
public static bool Check(double x) {
double min = -1e6, max = 1e6;
return x > min && x < max;
}
public static void Main()
{
Console.WriteLine($"NaN {Check(double.NaN)}"); // False
Console.WriteLine($"-inf {Check(double.NegativeInfinity)}"); // False
Console.WriteLine($"-1e7 {Check(-1e7)}"); // False
Console.WriteLine($"0 {Check(0)}"); // True
Console.WriteLine($"1e7 {Check(1e7)}"); // False
Console.WriteLine($"+inf {Check(double.PositiveInfinity)}"); // False
}
}
This should work
if(Double.IsNaN(value)||Double.IsInfinity(value) ){
//do nothing
}else{
chart1.Series["mySerie"].Points.AddY(value);
}
Double has a few static methods that could help you do this. If you want to check the different states individually you can use the following methods:
Double.IsInfinite(value); //returns true if the value is infinite
Double.IsNaN(value); //returns true if the value is NaN
As you want to disregard other non-double values, I would suggest using one of the following:
Double.IsNormal(value); //returns true if the value is normal
Double.IsSubnormal(value); //returns true if the value is subnormal
Double.IsFinite(value) //returns true if the value is zero, normal, or subnormal
Any of these will help filter your input, so use the one that matches the input that you need. IsFinite is the only one of the 3 I believe that will return true if the value is 0
The entire set of methods for the Double type can be found here
I have an int and a double, but as soon as I try to subtract the integer from the double, the following error is thrown:
Input string was not in a correct format.
Now lets look at the code:
double TotalNoRegis = values.Sum(); // This is a LIST and its = 1569
string otherFe ="600";
double totalafter;
if(otherFe != string.Empty || otherFe!= "") // This part works fine
{
totalafter = TotalNoRegis - Convert.ToInt32(otherFe); // Here the error is thrown
}
What am I doing wrong here? I looked at this Example, which is basically the same thing: int x = 1 and int y = 2 and then int this = x-y;
Please let me know if you know the issue here.
What am I doing wrong here?
Lots.
if(otherFe != string.Empty || otherFe!= "") // This part works fine
That's nonsensical code. string.Empty and "" are the same string.
Instead use
if (!string.IsNullOrEmpty(otherFe))
Moving on:
totalafter = TotalNoRegis - Convert.ToInt32(otherFe); // Here the error is thrown
You claim that the error is the subtraction, but it is not. The problem is in the ToInt32. You are passing some other string than the one you are showing.
The way I like to do this is by making an extension method:
static public class Extensions
{
public static int? ParseAsInteger(this string s) {
if (string.IsNullOrEmpty(s)) return null;
int i;
return int.TryParse(s, out i) ? (int?)i : (int?)null;
}
// Similarly write `ParseAsDouble` and so on.
}
Now you have an extension you can use:
double? totalAfter = TotalNoRegis - otherFe.ParseAsInteger();
(Or ParseAsDouble, or whatever.)
If otherFe was valid, then totalAfter has the total; if it was not, then it is null.
The lesson here is: move the type conversion logic into its own method which you can independently test. Then the logic at the call site of that method becomes simpler and easier to follow.
You should use an integer instead of a double, especially if you don't have a reason to use the double. So to rectify, you could simply do the following.
int total = values.Sum();
var other = "6000";
if(!string.IsNullOrEmpty(other))
if(int.TryParse(other, out int subtractor))
total -= subtractor;
If you require a double, then use but if you don't why bother? Also, you are subtracting fifteen hundred items from six thousand, your total after will always be negative or often be negative. Is that your desired intent?
Something to note, with the TryParse if it fails it'll skip the subtraction rather than fail like parse or convert would do. Also do you want the sum of the list or count?
I have a variable that is a decimal and i want to determine if it "is an int"
public bool IsanInt(decimal variable)
so if the variable passed in was 1, i want to return true
if it was 1.5, it would return false
.5 would be false
10 would be true
what is the best way to do this check?
Here you go:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(IsInt(3.0m)); // True
Console.WriteLine(IsInt(3.1m)); // False
}
public static bool IsInt(decimal variable)
{
return ((variable % 1) == 0);
}
}
Basically, that method is all you need. I just included the entire console program so that you can see the results.
EDIT:
So, after some brainstorming on the comments below, I found that it's incredibly difficult, if not impossible (I haven't found the way) to find if the value is decimal or "integer" if the decimal value being provided at its very high value. Decimal holds a higher value than even UInt64. When you run this line of code:
Console.WriteLine(Decimal.MaxValue - 0.5m);
Output:
79228162514264337593543950334
... you will see that it won't print the decimal value after the period. There is a maximum limitation that is forcing the truncation, so you'll never see that 0.5 being part of the that large value. My method can't fix that limitation. I'm not sure if there's anything that can do that within C# or .NET, but I'm all ears.
There's a good article on what you can and can't do with decimal... better than what MSDN provides in my opinion:
http://www.dotnetperls.com/decimal
public bool IsInteger(decimal value)
{
return value == Math.Round(value);
}
how about something like
return Math.Round(n) == n
I currently got the following method, which is returning me percent-values. For example for an item-price of $350,000 and a percentage of 7%, it returns 24,500.
public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
decimal result = 0m;
if (percentage != null)
{
try
{
result = Convert.ToDecimal(baseValue * percentage / 100m);
}
catch (OverflowException)
{
result = 0;
Logger.Warn("OverflowException caught in GetPercentValue() - should better be handled UI-Sided!");
}
}
return result;
}
I don't think this is handled the right way, so is there any way to avoid an exception in this situation?
An OverflowException is being thrown when a user enters an insane number like 999,999,999,999,999,999 and calculates 9999999999% of it. This way I can't check percentage or baseValue for <= decimal.MaxValue simply because they aren't... The calculation result itself then exceeds the decimal range.
This is an old question, but I ran into a similar issue, and thought to provide a possible alternate solution. The problem happens when some calculation of two numbers produces a number greater than a MaxValue. This causes an exception, and is hard to test in the usual way:
decimal existingValue = decimal.MaxValue;
decimal newValue = (decimal)100;
//doesn't work -- exception thrown here
if(existingValue + newValue <= decimal.MaxValue)
{
}
The solution that seems to work for me (without using a Try-Catch block) is to rewrite the equation, in this case as a subtraction:
if(decimal.MaxValue - existingValue >= newValue)
{
//DoSomething
}
MaxValue isn't exceeded because of the subtraction. I haven't tried a multiplication/division example, but I'm guessing it would work too.
The error handling should (most likely) be done outside the method. Right now you're hiding exceptions and returning wrong results (0 is returned when an error occures). The caller of your method cannot tell if the result is correct or if it's due to an OverflowException.
I'd rewrite the method like that:
public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
if (percentage == null)
return 0;
return baseValue*(percentage.Value/100);
}
And optionally add a validation method that the user can call to check the parameters before calling the real method.. validation errors could be displayed in the UI:
public static string ValidatePercentValue(decimal? percentage, decimal baseValue)
{
try
{
GetPercentValue(percentage, baseValue);
return null;
}
catch (Exception ex)
{
return ex.Message;
}
}
Besides that note that...
baseValue*(percentage.Value/100)
... is better than...
baseValue*percentage.Value/100
Try to calculate 100% of decimal.MaxValue. The first one works while the second one throws an OverflowException.
Handling integer overflow is a common task, but what's the best way to handle it in C#? Is there some syntactic sugar to make it simpler than with other languages? Or is this really the best way?
int x = foo();
int test = x * common;
if(test / common != x)
Console.WriteLine("oh noes!");
else
Console.WriteLine("safe!");
I haven't needed to use this often, but you can use the checked keyword:
int x = foo();
int test = checked(x * common);
Will result in a runtime exception if overflows. From MSDN:
In a checked context, if an expression produces a value that is
outside the range of the destination type, the result depends on
whether the expression is constant or non-constant. Constant
expressions cause compile time errors, while non-constant expressions
are evaluated at run time and raise exceptions.
I should also point out that there is another C# keyword, unchecked, which of course does the opposite of checked and ignores overflows. You might wonder when you'd ever use unchecked since it appears to be the default behavior. Well, there is a C# compiler option that defines how expressions outside of checked and unchecked are handled: /checked. You can set it under the advanced build settings of your project.
If you have a lot of expressions that need to be checked, the simplest thing to do would actually be to set the /checked build option. Then any expression that overflows, unless wrapped in unchecked, would result in a runtime exception.
Try the following
int x = foo();
try {
int test = checked (x * common);
Console.WriteLine("safe!");
} catch (OverflowException) {
Console.WriteLine("oh noes!");
}
The best way is as Micheal Said - use Checked keyword.
This can be done as :
int x = int.MaxValue;
try
{
checked
{
int test = x * 2;
Console.WriteLine("No Overflow!");
}
}
catch (OverflowException ex)
{
Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}
Sometimes, the simplest way is the best way. I can't think a better way to write what you wrote, but you can short it to:
int x = foo();
if ((x * common) / common != x)
Console.WriteLine("oh noes!");
else
Console.WriteLine("safe!");
Note that I didn't remove the x variable because it'd be foolish to call the foo() three times.
Old thread, but I just ran into this. I didn't want to use exceptions. What I ended up with was:
long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
do whatever you want with the overflow
return((int)a);
So, I ran into this far after the fact, and it mostly answered my question, but for my particular case (in the event anyone else has the same requirements), I wanted anything that would overflow the positive value of a signed int to just settle at int.MaxValue:
int x = int.MaxValue - 3;
int someval = foo();
try
{
x += someval;
}
catch (OverflowException)
{
x = int.MaxValue;
}