using a for loop to determine maximum value of an int variable

G

garyusenet

I'm trying to investigate the maximum size of different variable types.
I'm using INT as my starting variable for exploration. I know that the
maximum number that the int variable can take is: 65,535. But i'm
trying to write a program to test this, assuming I didn't know this
number in advance. I came up with the following but have two questions.
Maybe someone can help?

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int j = 0;
double i = 0;
for (i = 0; i < 9999999999999999999; i++)
{

j = (int)i;
Console.WriteLine(j.ToString());
///on error console.write(there was an error... this
was the error code)

}
}
}
}

q.1.
I want to have an idea of what is going on in my program. As you can
see, in my for loop I am writing the value of j to the screen on a new
line every time it is incremented. This is too slow. It seems to be
taking forever to scroll through the digits. My question is, is there a
way that I can display the value of j every, say, 10 thousand
increments?

q.2.
is there a way I can time how long the loop takes to complete, and at
the end of the loop display this time?

q.3
I'd like to output an error message to the screen when the variable
crashes because it's too small to hold the number being allocated to
it. How do i do this?

Thankyou,

Gary.
 
D

Dustin Campbell

I'm trying to investigate the maximum size of different variable
types. I'm using INT as my starting variable for exploration. I know
that the maximum number that the int variable can take is: 65,535.

Actually, that's the maximum size of a ushort. int has a maximum upper limit
of 2,147,483,647. In fact, you can see the upper limit by checking the MaxValue
field of int.
But i'm trying to write a program to test this, assuming I didn't know
this number in advance. I came up with the following but have two
questions. Maybe someone can help?

using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int j = 0;
double i = 0;
for (i = 0; i < 9999999999999999999; i++)
{
j = (int)i;
Console.WriteLine(j.ToString());
///on error console.write(there was an error... this
was the error code)
}
}
}
}
q.1.
I want to have an idea of what is going on in my program. As you can
see, in my for loop I am writing the value of j to the screen on a new
line every time it is incremented. This is too slow. It seems to be
taking forever to scroll through the digits. My question is, is there
a
way that I can display the value of j every, say, 10 thousand
increments?

sure. i += 10000
q.2.
is there a way I can time how long the loop takes to complete, and at
the end of the loop display this time?

If you're in .NET 2.0, try the System.Diagnostics.Stopwatch class.
q.3
I'd like to output an error message to the screen when the variable
crashes because it's too small to hold the number being allocated to
it. How do i do this?

Well, you shouldn't actually need to do this. It'll crash on its own and
display an error message to the console. However, you could wrap your code
in a try/catch block like this:

static void Main(string[] args)
{
try
{
// Your code here...
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

Best Regards,
Dustin Campbell
Developer Express Inc.
 
G

garyusenet

Thankyou very much Dustin your answers have answerd 90% of my questions
and have really helped me alot.

Although changing the for interation from 1, to a higher number works
for this test it doesn't really answer my for loop question, which was
probabally because I didn't put my question right in the first
instance! I was intrigued about the question when it came to me in this
example and still dont really know the answer.

My First Question is: -

With a for loop like so: -

for(i=0; i<9999999999; i++)
{

}

how can I do an action every nth interations of the loop? so for
instance everytime the loop has executed 10,000 times do something?

Also another question has come to me now as I have worked through your
answers.
My code is now displaying the value of of the integer variable to
screen and I'm not having to wait as long as i am incrementing it's
value by 500,000 every iteration. However. When the value gets to:
2145,000,000 all future increments don't generate an error.
Instead each future increment is displayed as: -2147483648.

I'm just wondering why an error isn't generated. And why the value
becomes negative, with a numerical value one greater than the actual
numerical value that the variable is permitted to hold?

Thanks!

Gary-

Dustin said:
I'm trying to investigate the maximum size of different variable
types. I'm using INT as my starting variable for exploration. I know
that the maximum number that the int variable can take is: 65,535.

Actually, that's the maximum size of a ushort. int has a maximum upper limit
of 2,147,483,647. In fact, you can see the upper limit by checking the MaxValue
field of int.
But i'm trying to write a program to test this, assuming I didn't know
this number in advance. I came up with the following but have two
questions. Maybe someone can help?

using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int j = 0;
double i = 0;
for (i = 0; i < 9999999999999999999; i++)
{
j = (int)i;
Console.WriteLine(j.ToString());
///on error console.write(there was an error... this
was the error code)
}
}
}
}
q.1.
I want to have an idea of what is going on in my program. As you can
see, in my for loop I am writing the value of j to the screen on a new
line every time it is incremented. This is too slow. It seems to be
taking forever to scroll through the digits. My question is, is there
a
way that I can display the value of j every, say, 10 thousand
increments?

sure. i += 10000
q.2.
is there a way I can time how long the loop takes to complete, and at
the end of the loop display this time?

If you're in .NET 2.0, try the System.Diagnostics.Stopwatch class.
q.3
I'd like to output an error message to the screen when the variable
crashes because it's too small to hold the number being allocated to
it. How do i do this?

Well, you shouldn't actually need to do this. It'll crash on its own and
display an error message to the console. However, you could wrap your code
in a try/catch block like this:

static void Main(string[] args)
{
try
{
// Your code here...
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

Best Regards,
Dustin Campbell
Developer Express Inc.
 
M

mc

how about: -

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Int32 Max= "+Int32.MaxValue.ToString());
}
}
}

I know it's a bit tongue and cheek, but surely this is all you trying to
achieve?

The MaxValue and MinValue constants are available for all sorts of
different variable types.

MC
 
T

Tom Porterfield

I'm trying to investigate the maximum size of different variable types.
I'm using INT as my starting variable for exploration. I know that the
maximum number that the int variable can take is: 65,535. But i'm
trying to write a program to test this, assuming I didn't know this
number in advance. I came up with the following but have two questions.
Maybe someone can help?

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int j = 0;
double i = 0;
for (i = 0; i < 9999999999999999999; i++)
{

j = (int)i;
Console.WriteLine(j.ToString());
///on error console.write(there was an error... this
was the error code)

}
}
}
}

To start with, System.Int16, Int32 and Int64 all have a static MaxValue
property. Accessing that is much faster than looping until an exception is
thrown.
q.1.
I want to have an idea of what is going on in my program. As you can
see, in my for loop I am writing the value of j to the screen on a new
line every time it is incremented. This is too slow. It seems to be
taking forever to scroll through the digits. My question is, is there a
way that I can display the value of j every, say, 10 thousand
increments?

if (j%10000 == 0)Console.WriteLine(j.ToString());
q.2.
is there a way I can time how long the loop takes to complete, and at
the end of the loop display this time?

As Dustin responded, System.Diagnostics.Stopwatch should help. If not .NET
2.0, you could create a DateTime object at the start of the loop, another at
the end, set both values to the static DateTime.Now and subract end from
start once the loop is finished. Ex:

DateTime start = DateTime.Now;
for ()
{
....
}
Console.WriteLine (DateTime.Now - start);
q.3
I'd like to output an error message to the screen when the variable
crashes because it's too small to hold the number being allocated to
it. How do i do this?

The problem here is it won't crash. if you try to cast a value that is too
large for an Int32 into an Int32, it simply loops. Try the following in
code:

double d = double.MaxValue
int x = (int)d;

This will not cause an exception and will instead set the value of x
to -2147483648. So you would need to check for a negative number and then
behave accordingly. Ex:

if (j < 0)
{
Console.WriteLine ("Max value is " + (i - 1));
break;
}

But again, System.Int32.MaxValue is the better way to get this value.
 
D

Dustin Campbell

Thankyou very much Dustin your answers have answerd 90% of my
questions and have really helped me alot.

Although changing the for interation from 1, to a higher number works
for this test it doesn't really answer my for loop question, which was
probabally because I didn't put my question right in the first
instance! I was intrigued about the question when it came to me in
this example and still dont really know the answer.

My First Question is: -

With a for loop like so: -

for(i=0; i<9999999999; i++)
{
}

how can I do an action every nth interations of the loop? so for
instance everytime the loop has executed 10,000 times do something?

Use modular arithmetic like this:

for(i=0; i<9999999999; i++)
{
if (i % 10000 == 0)
// do something...
}
Also another question has come to me now as I have worked through your
answers.
My code is now displaying the value of of the integer variable to
screen and I'm not having to wait as long as i am incrementing it's
value by 500,000 every iteration. However. When the value gets to:
2145,000,000 all future increments don't generate an error.
Instead each future increment is displayed as: -2147483648.
I'm just wondering why an error isn't generated. And why the value
becomes negative, with a numerical value one greater than the actual
numerical value that the variable is permitted to hold?

See Tom's excellent post on this thread.

Best Regards,
Dustin Campbell
Developer Express Inc.
 
M

Marc Gravell

how can I do an action every nth interations of the loop?

for(...) {
if(i % 10000==0) {
DoSomethingInteresting();
}
}
// perhaps DoSomethingInteresting() here if you always
// want it to fire at the end even if partly through a block

Marc
 
G

garyusenet

Thankyou these are exactly the answers I was looking for. I have two
final questions on the subject maybe someone would be kind enough to
answer them for me.

1.
Why isn't an error generated? Is this a floor with the .net error
checking?

2.
When I experiment with a uint instead of an int, and increment it by
500,000 at a time, i notice the value outputted to the console doesn't
steadily increase, but increases, then decreases, then increases etc...
why is this? what is going on?

Thanks,

Gary-
 
D

Dustin Campbell

Thankyou these are exactly the answers I was looking for. I have two
final questions on the subject maybe someone would be kind enough to
answer them for me.

1.
Why isn't an error generated? Is this a floor with the .net error
checking?

Try wrapping the expression with the "checked" keyword. This will cause the
runtime to throw an OverflowException.

j = checked((int)i);
2.
When I experiment with a uint instead of an int, and increment it by
500,000 at a time, i notice the value outputted to the console doesn't
steadily increase, but increases, then decreases, then increases
etc...
why is this? what is going on?

The uint variable is overflowing and then being set to 0 + the overflow amount.
For example:

Best Regards,
Dustin Campbell
Developer Express Inc.
 
T

Tom Porterfield

Thankyou these are exactly the answers I was looking for. I have two
final questions on the subject maybe someone would be kind enough to
answer them for me.

1.
Why isn't an error generated? Is this a floor with the .net error
checking?

2.
When I experiment with a uint instead of an int, and increment it by
500,000 at a time, i notice the value outputted to the console doesn't
steadily increase, but increases, then decreases, then increases etc...
why is this? what is going on?

C# statements can execute in either checked or unchecked context. In a
checked context, arithmetic overflow raises an exception. In an unchecked
context, arithmetic overflow is ignored and the result is truncated.

checked - Specify checked context.
unchecked - Specify unchecked context.
If neither checked nor unchecked is specified, the default context depends
on external factors such as compiler options.

The following operations are affected by the overflow checking:

Expressions using the following predefined operators on integral types:
++ - - (unary) + - * /

Explicit numeric conversions between integral types.
The /checked compiler option lets you specify checked or unchecked context
for all integer arithmetic statements that are not explicitly in the scope
of a checked or unchecked keyword.

Ex:

int j = 0;
j = (checked(int)i);

Another option, instead of casting and explicitly stating a checked context
is to use the Convert class's ToInt32 method.

j = Convert.ToInt32(i);

This will throw an exception if there is on overflow regardless of whether
or not you remember to run it in a checked context.
 
G

garyusenet

Thank you very much.

Dustin said:
Try wrapping the expression with the "checked" keyword. This will cause the
runtime to throw an OverflowException.

j = checked((int)i);


The uint variable is overflowing and then being set to 0 + the overflow amount.
For example:

Best Regards,
Dustin Campbell
Developer Express Inc.
 
G

garyusenet

Thankyou.

May i ask - what the difference 'under the bonnet' is between Convert
and a manual cast?
I'm quite interested to know, I now know convert error checks from the
previous posters comments, but is there any other difference?

Thankyou

Gary-
 
D

Dustin Campbell

May i ask - what the difference 'under the bonnet' is between Convert
and a manual cast?
I'm quite interested to know, I now know convert error checks from the
previous posters comments, but is there any other difference?

Using the .NET Reflector (http://www.aisto.com/roeder/dotnet/) to disassemble
"Convert.ToInt32(Double): Int32" reveals C# code that looks like this:

public static int ToInt32(double value)
{
if (value >= 0)
{
if (value < 2147483647.5)
{
int num1 = (int) value;
double num2 = value - num1;
if ((num2 > 0.5) || ((num2 == 0.5) && ((num1 & 1) != 0)))
{
num1++;
}
return num1;
}
}
else if (value >= -2147483648.5)
{
int num3 = (int) value;
double num4 = value - num3;
if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & 1) != 0)))
{
num3--;
}
return num3;
}
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}

Best Regards,
Dustin Campbell
Developer Express Inc
 
T

Tom Porterfield

Thankyou.

May i ask - what the difference 'under the bonnet' is between Convert
and a manual cast?
I'm quite interested to know, I now know convert error checks from the
previous posters comments, but is there any other difference?

Casting truncates, Convert rounds.

double d = 0.6;
int i = (int)d; //i = 0
int j = Convert.ToInt32(d); //j = 1
 
B

Bill Butler

I'm trying to investigate the maximum size of different variable
types.
I'm using INT as my starting variable for exploration. I know that the
maximum number that the int variable can take is: 65,535. But i'm
trying to write a program to test this, assuming I didn't know this
number in advance. I came up with the following but have two
questions.
Maybe someone can help?
<snip>

Others have already pointed out the modulus trick, but there is another
problem with your method...the algorithm is linear. This is not a big
deal with small data types, but it is not the best way to go.

A better approach is an algorithm based on a binary search
Here is a sample

int x = 1;
int y = 0;

Console.WriteLine("Get in the right neighborhood");
Console.WriteLine("-----------------------------");
while(x > y)
{
y = x;
x*=2;
Console.WriteLine("{0}", y);
}

Console.WriteLine();
Console.WriteLine("Narrow it down");//
Console.WriteLine("-----------------------------");

int delta = (int)(y/2);
while ((int)(y + 1) > y)
{
if (y + delta > 0)
y += delta;
delta /=2;
Console.WriteLine("{0} ", y);
}

This will work for all of the integral data types.
simply replace the (int) with whatever type you would like to test and
then recompile.

If you wish to do the same thing for floating point numbers you need a
slightly different approach

Single x = 1;
Single y = 0;


Console.WriteLine("Get in the right neighborhood");
Console.WriteLine("-----------------------------");
while(!Single.IsInfinity(x))
{
y = x;
x*=2;
Console.WriteLine("{0}", y);
}

Console.WriteLine();
Console.WriteLine("Narrow it down");//
Console.WriteLine("-----------------------------");

Single delta = y/2;
while (!Single.IsInfinity(y))
{
if (y + delta > 0)
y += delta;
delta /=2;
Console.WriteLine("{0} delta:{1}", y, delta);
}

Hope this helps
Bill
 
L

Lucian Wischik

I want to have an idea of what is going on in my program. As you can
see, in my for loop I am writing the value of j to the screen on a new
line every time it is incremented. This is too slow. It seems to be
taking forever to scroll through the digits. My question is, is there a
way that I can display the value of j every, say, 10 thousand
increments?

I'm going to give some algorithmic advice. (even though it's rendered
irrelevant by the other, better, solutions for finding MAXINT in this
thread).

To explore a vast linear space like this, iterating is a bad idea as
you've found. But also displaying once every 10,000 incremements is a
bad idea because the interval "10,000" is arbitrary and potentially
inefficient.

You could instead start at 0, then 1, then 2, then 4, then 8, doubling
each time. Eventually you'll get too far. Therefore the true answer
lies somewhere in between the final two numbers you checked, say 16384
and 32768. So pick a number half way between these two. Does it
succeed? If so the true answer is in the upper half. If not the true
answer is in the bottom half. And keep on binary subdividing in this
way.

PS. it won't work for finding maxint, of course. But it's worth
keeping in mind for the next time you have to search for a number.
 
P

per9000

Hi,

this might not solve your problem better, but since no one mentioned
this I feel urged to:

A loop does not have to be
// N is a big number
for (int i = 0; i < N; i++)
{
Console.WriteLine(i);
}

It could just as well be
for (int i = 0; i < N; i += 1000)
{
Console.WriteLine(i);
}

The first one should produce 0,1,2,3,4...
the second one 0, 1000, 2000, 3000, ...

You can also use several variables in your for loop.
for (int i = 0, j = 3; i * j < 300; i++, j *= 2)
{
Console.WriteLine("i: {0}, j: {1}", i, j);
}

Produces
i: 0, j: 3
i: 1, j: 6
i: 2, j: 12
i: 3, j: 24
i: 4, j: 48


But, something that surprised me (a lot!) is that you seem NOT to be
allowed to mix int's and doubles in the for-loop (can someone please
correct me if this is wrong - it seems unreasonable that you can not do
this)

for (double j = 3.14, int i = 0; i * j < 300; i++, j *= 1.1)
{
Console.WriteLine("i: {0}, j: {1}", i, j);
}

compiler output:
Error 1
Identifier expected, 'int' is a keyword C:\...\Temporary
Projects\ConsoleApplication1\Program.cs 17 29 ConsoleApplication1


Cheers,
Per
 
G

garyusenet

Wow a lot to take in there, thankyou all for your invaluable advice.
I'll try to get my head around it today!

Thankyou,

Gary.
 
G

garyusenet

I'm trying to understand the following: -

static void Main(string[] args)
{
int x = 1;
int y = 0;

Console.WriteLine("Get in the right neighborhood");
Console.WriteLine("-----------------------------");
while (x > y)
{
y = x;
x *= 2;
Console.WriteLine("{0}", y);
}

Console.WriteLine();
Console.WriteLine("Narrow it down");//
Console.WriteLine("-----------------------------");

int delta = (int)(y / 2);
while ((int)(y + 1) > y)
{
if (y + delta > 0)
y += delta;
delta /= 2;
Console.WriteLine("{0} ", y);
}


}

Now I understand the first loop. I can see that it doubles the value of
the variable each time until it becomes negative indicating that an
error has occured.

I cant understand what is going on in the second loop (or more
preciscesly why, what is going on in the second loop, is happeneing) -
why divide y by 2 for instance?

Can someone please go through the second loop and comment it for me so
I understand what is happening.

Many Thanks,

Gary-
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

macro substitution in C# 2
determine if int is power of 2 3
why do I get compile error 2
locking an int 31
Variable vs. child scopes 3
access a variable using a value from db column for its name. 12
for loop 15
b-tree 11

Top