What's up with this, anyway? I do a simple multiplication:
Int64 x = 11111111111;
Int64 y = 11111111111;
Int64 z = x * y;
And at the end of the multiplication, z shows a value of:
-5670418394979206991
This has clearly overflowed, but no exception is raised. I'd like one to be raised, but...
Note that this is on Windows Phone 7, but I don't think this has any bearing on the issue. Or does it?
You can use a checked block as pointed out already by other answers:
checked
{
long x = 11111111111;
long y = 11111111111;
long z = checked(x * y);
// ...
}
Which results in an exception:
OverflowException: Arithmetic operation resulted in an overflow.
If you are just doing a single operation where you need checking you can use a checked expression instead:
long x = 11111111111;
long y = 11111111111;
long z = checked(x * y);
You can also set the /checked compiler option to have the default be checked.
To set this compiler option in the Visual Studio development environment:
Open the project's Property Pages dialog box. For details, see Setting Visual C# Project Properties.
Click the Configuration Properties folder.
Click the Build property page.
Modify the Check for Arithmetic Overflow/Underflow property.
If you change the default to checked you can use unchecked blocks or expressions to get the unchecked behaviour again.
Check it:
checked
{
Int64 x = 11111111111;
Int64 y = 11111111111;
Int64 z = x * y;
}
Try:
checked
{
Int64 x = 11111111111;
Int64 y = 11111111111;
Int64 z = x * y;
}
Compiler assumes you want to do it that way and proceed with the Overflow. If overflow needs to be considered as exception for the operation, wrap the operation around checked and it will throw an exception at runtime.
checked
{
Int64 x = 11111111111;
Int64 y = 11111111111;
Int64 z = x * y;
}
System.OverflowException: An exception
of type System.OverflowException was
thrown.
Related
So, I'm learning the code for the SplitMix64 generator and came upon this part here:
uint64_t z = (x += 0x9e3779b97f4a7c15);
Not being a C programmer, I don't really understand this construct.
Does the above mean z gets assigned value of x after x is incremented, like so:
x += 0x9e3779b97f4a7c15;
z = x;
Or does that mean z gets the value of x before x is incremented, like so:
z = x;
x += 0x9e3779b97f4a7c15;
And also, does the same behavior happen in C# ?
z gets assigned value of x after x is incremented. Think of it like this:
z = (x = x + 0x9e3779b97f4a7c15);
The return value of an assignment is always the value of the left-hand side of the assignment after the assignment is completed.
Ive seen the following syntax in a couple of code samples, it looks pretty obvious, but not in the context that i saw it in,
so can someone confirm
var x = 1
var y = 2
var z = 3
x = y = z
so in essence does this mean that
x and y both equal z?
tried to google this, and couldn't find the syntax, also looked in murach .net books with no luck
The assignment operator returns the value being assigned as it's result
The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result.
So
x = y = z;
Is parsed as
x = (y = z);
And this is equivalent to
y = z;
x = y;
In the end, x, and y are assigned the same value as z (in this case, 3).
This will indeed set x and y to the value of z, however to see why you can parenthesize the expression:
x = (y = z);
In this case the y = z expression will return the new value for y (in this case 3), and set x to that value.
This works for very long expressions too:
x = y = z = a = b
x = (y = (z = (a = b)))
Where x, y, z and a will be set to the value of b.
EDIT:
Also remember the order of precedence of operators when using this method of reading into a long expression, while its not a good practice to create huge chained statements you do sometimes see it in code online, another (and better) way you can use to read confusing statements like this is to think of the syntax tree that is generated.
Ehm, yes that is correct :).
x, y and x will all be 3 as you can assign values like that.
you can make the chain as long as you like too.
a = b = c = d;
all preceding values would be the value of d
This question already has answers here:
Cast operation precedence in C#
(3 answers)
Closed 8 years ago.
What is the precedence of a cast in c#? For example in the following code, will z be less than or equal to two?
double x = 4.5;
double y = 2.1;
double z = (int) x / y;
The cast beats all binary operators for binding. Hence (int)x / y means ((int)x)/y.
On the other hand, you should always prefer readable code to clever code, so since you don't know you should write the following instead:
((int)x) / y
Note that brackets are free, and make your code more readable.
Less than:
using System;
public class Test
{
public static void Main()
{
double x = 4.5;
double y = 2.1;
double z = (int) x / y;
Console.WriteLine(z);
}
}
See here: http://ideone.com/fhg5ai
z will be less than two:
double x = 4.5;
double y = 2.1;
double z = (int) x / y;
Console.WriteLine(z); //1.9047619047619
Your code is really doing this: ((int)x) / y, which may or may not be your expected output.
The equation is pretty simple, int = int * int / int; However, the multiplication of the ints could get too big, I'm trying to cast everything up to Int64s before doing it and then cast the result back down to an int. Thus I have:
int = (int)((Int64)int * (Int64)int / (Int64)int);
and it's complaining about all three of the Int64 casts.
Note: the target is x86 as I'm using a 32-bit only library. The machine itself is 64-bit. I could understand it with x64 target.
Am I missing something?
Does Resharper not understand the problem of intermediate values overflowing?
Int16 a = 1000;
Int16 b = 40;
var c = a * b; // c is Int32 because compiler does not want overflow
// The cast makes a3 Int64
// No need to cast a1 because all operations involving Int64
// will be Int64 to ensure no overflows when arithmetic operations are performed
var a3 = a1 * (Int64)a2;
Same for :
var a3 = (Int64)a1 * a2;
Resharper is a smart as you know, it gives the warning for all the 3 casts in your code because any 1 of them makes same sense.
Edit:
One more thing, all the operations on the right are evaluated and output is Int64 after the 1 cast done. The final int cast will work on the finally calculated value and it is explicit cast to int as Int64 cannot be directly cast to int (preventing overflow). There are no intermediate value overflows.
The very first cast produces an Int64. Int64 * int is Int64. Divided by int is Int64.
casting one of them is enough
int x, y, z, w;
x = y = z = int.MaxValue;
look at the behavior below and you'll understand it all
textBox1.Text = ((Int64)x * y).ToString();
output: 4611686014132420609
textBox2.Text = (x * y).ToString();
output: 1
textBox3.Text = ((int)((Int64)x * (Int64)y / (Int64)z)).ToString();
output: 2147483647
I was very surprised when I found out my code wasn't working so I created a console application to see where the problem lies and I've got even more surprised when I saw the code below returns 0
static void Main(string[] args)
{
float test = 140 / 1058;
Console.WriteLine(test);
Console.ReadLine();
}
I'm trying to get the result in % and put it in a progress(meaning (140 / 1058) * 100) bar on my application,the second value(1058) is actually ulong type in my application,but that doesn't seem to be the problem.
The question is - where the problem is?
You are using integer arithmetic and then converting the result to a float. Use floating-point arithmetic instead:
float test = 140f / 1058f;
The problem is that you are dividing integers and not floats. Only the result is a float. Change the code to be the following
float test = 140f / 1058f;
EDIT
John mentioned that there is a variable of type ulong. If that's the case then just use a cast opeartion
ulong value = GetTheValue();
float test = 140f / ((float)value);
Note, there is a possible loss of precision here since you're going from ulong to float.
This will work the way you expect ...
float test = (float)140 / (float)1058;
By the way, your code works fine for me (prints a 0.1323251 to the console).
The division being performed is integer division. Replace
float test = 140 / 1058;
with
float test = 140f / 1058;
to force floating-point division.
In general, if you have
int x;
int y;
and want to perform floating-point division then you must cast either x or y to a float as in
float f = ((float) x) / y;