PC Review


Reply
Thread Tools Rate Thread

Arithmetic Division

 
 
Joe Cool
Guest
Posts: n/a
 
      5th May 2007
Hello, I am using VS2005. I am trying to convert a VB.NET app to
C#.NET. The VB app uses a progress meter to indiate how far a file has
been read. I use the following assignment statement in VB:

Progress.Value = (lFileReadCount / fi.Length) * 100

lFileReadCount is a Long that contains the current number of bytes
read. fi is a FileInfo object of the file being read. Progress is
shown as a percentage.

In C# the statement is:

Progress.Value = (lFileReadCount / fi.Length) * 100;

Obviously the only difference is the semi-colon at the end. Problem
is, the value of the progress meter never changes from zero.

I put in debug statements and lFileReadCount and fi.Length are what
you would expect. I also put in a debug statement to display the
result of the arithmentic operation, and the result is ALWAYS ZERO!!!

What gives?!?!?
 
Reply With Quote
 
 
 
 
Morten Wennevik [C# MVP]
Guest
Posts: n/a
 
      5th May 2007
Hi Joe,

Did you specify the range of the Progress bar?
Check Maximum and Minimum and verify that Value isn't outside that range..


On Sat, 05 May 2007 20:45:32 +0200, Joe Cool <(E-Mail Removed)> wrote:

> Hello, I am using VS2005. I am trying to convert a VB.NET app to
> C#.NET. The VB app uses a progress meter to indiate how far a file has
> been read. I use the following assignment statement in VB:
>
> Progress.Value = (lFileReadCount / fi.Length) * 100
>
> lFileReadCount is a Long that contains the current number of bytes
> read. fi is a FileInfo object of the file being read. Progress is
> shown as a percentage.
>
> In C# the statement is:
>
> Progress.Value = (lFileReadCount / fi.Length) * 100;
>
> Obviously the only difference is the semi-colon at the end. Problem
> is, the value of the progress meter never changes from zero.
>
> I put in debug statements and lFileReadCount and fi.Length are what
> you would expect. I also put in a debug statement to display the
> result of the arithmentic operation, and the result is ALWAYS ZERO!!!
>
> What gives?!?!?
>




--
Happy coding!
Morten Wennevik [C# MVP]
 
Reply With Quote
 
Alberto Poblacion
Guest
Posts: n/a
 
      5th May 2007
"Joe Cool" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello, I am using VS2005. I am trying to convert a VB.NET app to
> C#.NET. The VB app uses a progress meter to indiate how far a file has
> been read. I use the following assignment statement in VB:
>
> Progress.Value = (lFileReadCount / fi.Length) * 100
>
> lFileReadCount is a Long that contains the current number of bytes
> read. fi is a FileInfo object of the file being read. Progress is
> shown as a percentage.
>
> In C# the statement is:
>
> Progress.Value = (lFileReadCount / fi.Length) * 100;
>
> Obviously the only difference is the semi-colon at the end. Problem
> is, the value of the progress meter never changes from zero.
>
> I put in debug statements and lFileReadCount and fi.Length are what
> you would expect. I also put in a debug statement to display the
> result of the arithmentic operation, and the result is ALWAYS ZERO!!!



The "/" in C#, when aplied to two integer values, is not equivalent to
the "/" in VB, but rather to the "\" in VB. That is, it performs INTEGER
division. Since lFileReadCount is always smaller than fi.Length, it always
yields zero.

What VB does is a floating point division, so it gives a result of zero
dot something, which is then multiplied by 100, giving a value which is then
converted implicitly to integer when assigned to Progress.Value. You would
have spotted this last implicit conversion if the compilation of the VB
program used "Option Strict On".

If you want C# to do a similar operation as VB, you can do it like this:
Progress.Value =(int)(((double)lFileReadCount / (double)fi.Length) *
100);

 
Reply With Quote
 
Joe Cool
Guest
Posts: n/a
 
      5th May 2007
On Sat, 05 May 2007 21:08:06 +0200, "Morten Wennevik [C# MVP]"
<(E-Mail Removed)> wrote:

>Hi Joe,
>
>Did you specify the range of the Progress bar?
>Check Maximum and Minimum and verify that Value isn't outside that range.
>


Remember, I am attempting to calculate a percentage, which should
range from 0 to 100. And the default maximum value of a progress bar
is 100.

>
>On Sat, 05 May 2007 20:45:32 +0200, Joe Cool <(E-Mail Removed)> wrote:
>
>> Hello, I am using VS2005. I am trying to convert a VB.NET app to
>> C#.NET. The VB app uses a progress meter to indiate how far a file has
>> been read. I use the following assignment statement in VB:
>>
>> Progress.Value = (lFileReadCount / fi.Length) * 100
>>
>> lFileReadCount is a Long that contains the current number of bytes
>> read. fi is a FileInfo object of the file being read. Progress is
>> shown as a percentage.
>>
>> In C# the statement is:
>>
>> Progress.Value = (lFileReadCount / fi.Length) * 100;
>>
>> Obviously the only difference is the semi-colon at the end. Problem
>> is, the value of the progress meter never changes from zero.
>>
>> I put in debug statements and lFileReadCount and fi.Length are what
>> you would expect. I also put in a debug statement to display the
>> result of the arithmentic operation, and the result is ALWAYS ZERO!!!
>>
>> What gives?!?!?
>>

 
Reply With Quote
 
Joe Cool
Guest
Posts: n/a
 
      5th May 2007
On Sat, 5 May 2007 21:11:02 +0200, "Alberto Poblacion"
<earthling-(E-Mail Removed)> wrote:

>"Joe Cool" <(E-Mail Removed)> wrote in message
>news:(E-Mail Removed)...
>> Hello, I am using VS2005. I am trying to convert a VB.NET app to
>> C#.NET. The VB app uses a progress meter to indiate how far a file has
>> been read. I use the following assignment statement in VB:
>>
>> Progress.Value = (lFileReadCount / fi.Length) * 100
>>
>> lFileReadCount is a Long that contains the current number of bytes
>> read. fi is a FileInfo object of the file being read. Progress is
>> shown as a percentage.
>>
>> In C# the statement is:
>>
>> Progress.Value = (lFileReadCount / fi.Length) * 100;
>>
>> Obviously the only difference is the semi-colon at the end. Problem
>> is, the value of the progress meter never changes from zero.
>>
>> I put in debug statements and lFileReadCount and fi.Length are what
>> you would expect. I also put in a debug statement to display the
>> result of the arithmentic operation, and the result is ALWAYS ZERO!!!

>
>
> The "/" in C#, when aplied to two integer values, is not equivalent to
>the "/" in VB, but rather to the "\" in VB. That is, it performs INTEGER
>division. Since lFileReadCount is always smaller than fi.Length, it always
>yields zero.
>
> What VB does is a floating point division, so it gives a result of zero
>dot something, which is then multiplied by 100, giving a value which is then
>converted implicitly to integer when assigned to Progress.Value. You would
>have spotted this last implicit conversion if the compilation of the VB
>program used "Option Strict On".
>
> If you want C# to do a similar operation as VB, you can do it like this:
> Progress.Value =(int)(((double)lFileReadCount / (double)fi.Length) *
>100);


PERFECT! Thank you.

My company is switching from VB to C#.NET so I am practising
converting some VB.NET apps I wrote for personal use. The more I use
C# the more I like it, but situations like this ain't helping!!!

VB does a HELL of a lot more implicit datatype conversions and it
seems I almost have to type EVERY conversion in C#.
 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      5th May 2007
Joe Cool <(E-Mail Removed)> wrote:
> PERFECT! Thank you.
>
> My company is switching from VB to C#.NET so I am practising
> converting some VB.NET apps I wrote for personal use. The more I use
> C# the more I like it, but situations like this ain't helping!!!
>
> VB does a HELL of a lot more implicit datatype conversions and it
> seems I almost have to type EVERY conversion in C#.


Yes. This is a good thing, IMO - it makes it much clearer where
conversions are taking place, which means it's less likely to happen
without you knowing. As Alberto pointed out, with Option Strict On
you'd have had to do the conversion from floating point back to integer
in VB.NET too.

Not all conversions are explicit, of course, and the situation you've
got here is slightly different - there *is* an implicit conversion from
int to double - it's the types used for the *operation* which are
important. The C family of languages (from which C# derives) has always
made / do integer arithmetic when both of the operands are integers.

Note that you only need *one* of the casts to double in the division -
if either operand is a floating point one, floating point division will
be used instead of integer division.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Alun Harford
Guest
Posts: n/a
 
      6th May 2007
Joe Cool wrote:
> Hello, I am using VS2005. I am trying to convert a VB.NET app to
> C#.NET. The VB app uses a progress meter to indiate how far a file has
> been read. I use the following assignment statement in VB:
>
> Progress.Value = (lFileReadCount / fi.Length) * 100
>
> lFileReadCount is a Long that contains the current number of bytes
> read. fi is a FileInfo object of the file being read. Progress is
> shown as a percentage.
>
> In C# the statement is:
>
> Progress.Value = (lFileReadCount / fi.Length) * 100;


/ does integer division.
So this gets evaluated as (lFileReadCount / fi.Length) * 100 = 0 * 100=0

You could do horrible things converting to floats, or you could just
remember that instruction order matters.

Try:

Progress.Value = (lFileReadCount * 100) / fi.Length

Alun Harford
 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      6th May 2007
Alun Harford <(E-Mail Removed)> wrote:
> > Progress.Value = (lFileReadCount / fi.Length) * 100;

>
> / does integer division.
> So this gets evaluated as (lFileReadCount / fi.Length) * 100 = 0 * 100=0
>
> You could do horrible things converting to floats, or you could just
> remember that instruction order matters.
>
> Try:
>
> Progress.Value = (lFileReadCount * 100) / fi.Length


Note that there's a potential problem with this, in that you end up
with temporary values which are larger. In this case, if lFileReadCount
is an int variable you will run into problems with files more than
~21MB, as at some point lFileReadCount will be greater than
int.MaxValue/100.

It's certainly a cleaner looking line than the version with floating
point though

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Alun Harford
Guest
Posts: n/a
 
      6th May 2007
Jon Skeet [C# MVP] wrote:
> Alun Harford <(E-Mail Removed)> wrote:
>>> Progress.Value = (lFileReadCount / fi.Length) * 100;

>> / does integer division.
>> So this gets evaluated as (lFileReadCount / fi.Length) * 100 = 0 * 100=0
>>
>> You could do horrible things converting to floats, or you could just
>> remember that instruction order matters.
>>
>> Try:
>>
>> Progress.Value = (lFileReadCount * 100) / fi.Length

>
> Note that there's a potential problem with this, in that you end up
> with temporary values which are larger. In this case, if lFileReadCount
> is an int variable you will run into problems with files more than
> ~21MB, as at some point lFileReadCount will be greater than
> int.MaxValue/100.


The OP said it was a long. So you're nice and safe from overflow. :-)

That means Progress.Value must take a long, which is odd, but the OP's
code would only compile if that were the case.

Alun Harford
 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      6th May 2007
Alun Harford <(E-Mail Removed)> wrote:
> > Note that there's a potential problem with this, in that you end up
> > with temporary values which are larger. In this case, if lFileReadCount
> > is an int variable you will run into problems with files more than
> > ~21MB, as at some point lFileReadCount will be greater than
> > int.MaxValue/100.

>
> The OP said it was a long. So you're nice and safe from overflow. :-)


Ah, missed that bit.

> That means Progress.Value must take a long, which is odd, but the OP's
> code would only compile if that were the case.


Hmm. That is indeed very odd - presumably this isn't
System.Windows.Forms.ProgressBar then...

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
division in access to round-up if division not whole number ddiel Microsoft Access VBA Modules 10 30th Dec 2009 12:59 AM
Sql for arithmetic (division) =?Utf-8?B?c2ViYXN0aWNv?= Microsoft Access Queries 3 23rd May 2007 07:40 PM
question about 32-bit interger arithmetic vs. 32-bit float arithmetic zhihang.wang@gmail.com Computer Hardware 2 9th Jan 2006 02:21 AM
is there a division symbol. As in a maths division symbol =?Utf-8?B?Q3VwQ2FrZQ==?= Microsoft Word Document Management 3 15th Nov 2005 12:38 AM
Passmark Performance Test, Division, Floating Point Division, 2DShapes @(none) Computer Hardware 0 19th Aug 2004 11:57 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 04:25 PM.