473,386 Members | 1,720 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Assigning the result of a '/' division to an integer type causes rounding

Does anyone know the logic behind why in VB.NET the result of a
floating-point division ('/') is -rounded- on being converted to an
integer type, such as with statements like

Dim x As Integer = 2/3 'after assignment, x is 1, whereas a sane person
would say it should be 0

Does Microsoft have a reason for this design decision? I understand
that this type of rounding can reduce the overall error in long
computation chains by reducing the amount of error that accumulates
from ignoring the fractional part of intermediate results, but why
specifically does VB.NET do this? It seems very unnatural IMO; I can't
think of any other programming language that does this. It would make
much more sense if VB.NET performed floating-point to integer
conversions by simply dropping everything after the decimal. It makes
even less sense to have to use the integer division ('\') operator when
you need to make it explicit that you -don't- want it to perform
rounding. On that note, I think they got the '/' and '\' syntax
backwards. IMHO...

The '/' operator (what is currently
floating-point-division-with-rounding-on-conversion-to-integer) should
behave similar to how the '/' operator behaves in most other
programming languages: the division should be performed in
floating-point; if the result is then converted to an integer, the
fractional part should simply be thrown out without any rounding.

The '\' operator (so-called "integer division") should do what '/'
currently does in VB.NET. That is, it should perform the division and
then round up if the fractional part is greater than or equal to 0.5.

Think about it. Most programming languages only have one division
operator, which is usually written with '/' by convention. And by
convention, '/' in most programming languages means what '\' (integer
division) means in VB.NET. VB.NET is completely upside-down. Sometimes
I get the feeling that Microsoft intentionally goes out of its way to
avoid following conventions or precedent, or anything that might be
considered 'normal.' ;-)

That's my rant. I'm interested to see what everyone else thinks of all
this, and if anyone indeed knows why Microsoft chose to do division
this way.

--
Mike S

Jun 14 '06 #1
10 3153
"Mike S" <mg******@netscape.net> schrieb:
Does anyone know the logic behind why in VB.NET the result of a
floating-point division ('/') is -rounded- on being converted to an
integer type, such as with statements like

Dim x As Integer = 2/3 'after assignment, x is 1, whereas a sane person
would say it should be 0


I recommend to turn 'Option Strict' on. The rounding doesn't occur as part
of the division, it's caused by the implicit conversion of the division's
result, which is 0.666..., to 'Integer'. 0.666... is rounded to the
integral number 1 for obvious reasons. With 'Option Strict On' you'll have
to write 'Dim x As Integer = CInt(2 / 3)'.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Jun 14 '06 #2

Herfried K. Wagner [MVP] wrote:
"Mike S" <mg******@netscape.net> schrieb:
Does anyone know the logic behind why in VB.NET the result of a
floating-point division ('/') is -rounded- on being converted to an
integer type, such as with statements like

Dim x As Integer = 2/3 'after assignment, x is 1, whereas a sane person
would say it should be 0
I recommend to turn 'Option Strict' on. The rounding doesn't occur as part
of the division, it's caused by the implicit conversion of the division's
result,


Right. I know it's not part of the division. That's why I asked why
does it round the result *on being converted to* an integer type.
which is 0.666..., to 'Integer'. 0.666... is rounded to the
integral number 1 for obvious reasons.
Whether it's "obvious" is a matter of experience, I guess. To me, it
would be obvious if the the conversion caused the fractional part to be
discarded, rather than for the rounding to occur. For example, if you
do this in C++:

#include <iostream>

int main(void)
{
int x = 2/3;
std::cout << x << std::endl;
return 0;
}

The output will be '0'. I think this is the obvious result because, as
I said, most programming languages will do integer conversions by
dropping the fractional part of the answer. The fact that in VB.NET,
the integer conversion causes the answer to be rounded instead is
counter-intuitive if you come from a different language background. My
point is that most, if not all, other programming languages would
convert 0.66666 to integer 0, not 1.
With 'Option Strict On' you'll have
to write 'Dim x As Integer = CInt(2 / 3)'.


That's just a more verbose way to do the same thing as:

Dim x As Integer = 2 / 3
with Option Strict Off (which is the compiler default anyway).

CInt(2 / 3) is still 1. My argument is that CInt(2 / 3) = 0 would be
more logical and by extension implicit integer conversions should also
not round, since an implicit integer conversion should (obviously) be
the same as what an explicit CInt would give.

I'm not hoping to change the VB.NET language specs, I'm simply pointing
out that this is awfully counter-intuitive behavior IMHO...

--
Mike S

Jun 14 '06 #3
"Mike S" <mg******@netscape.net> schrieb:
I'm not hoping to change the VB.NET language specs, I'm simply pointing
out that this is awfully counter-intuitive behavior IMHO...


Well, for somebody like me who is having a strong BASIC background the
behavior seems very intuitive. I don't think that stripping off everything
after the decimal point is more intuitive than rounding when performing the
conversion. Moreover I think that rounding is more "natural" because it
better preserves the actual value. It's simply more high-level.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Jun 14 '06 #4
I would have to agree with Herfried. Coming from a strong VB background,
the rounding method is preferred. Also I don't have a huge mathmatics background..
but If on paper I work 2/3 out to be .666666 I naturally round it to 1 if
I need it as an integer. The rounding method is how my brain works naturally,
so I like it.

-Boo
"Mike S" <mg******@netscape.net> schrieb:
I'm not hoping to change the VB.NET language specs, I'm simply
pointing out that this is awfully counter-intuitive behavior IMHO...

Well, for somebody like me who is having a strong BASIC background the
behavior seems very intuitive. I don't think that stripping off
everything after the decimal point is more intuitive than rounding
when performing the conversion. Moreover I think that rounding is
more "natural" because it better preserves the actual value. It's
simply more high-level.

Jun 14 '06 #5
On 2006-06-14, Mike S <mg******@netscape.net> wrote:

Herfried K. Wagner [MVP] wrote:
"Mike S" <mg******@netscape.net> schrieb:
> Dim x As Integer = 2/3 'after assignment, x is 1, whereas a sane person
> would say it should be 0


I recommend to turn 'Option Strict' on. The rounding doesn't occur as part
of the division, it's caused by the implicit conversion of the division's
result,


Right. I know it's not part of the division. That's why I asked why
does it round the result *on being converted to* an integer type.


OTOH,

Dim j as Integer = 2
Dim i As Integer = CInt(j/3)

i will now be 0, as most non-VB.Net programmers probably expect, while
CInt(2/3) returns 1.

The moral of the story is to watch out for the CType/CInt/CStr
functions. Visual Basic had lots of features that seem very
counterintuitive for those from other language backgrounds. The
C-functions, and much of the VisualBasic namespace methods, often try to
reproduce this behavior.

Whether you see this behavior as incredibly helpful or incredibly
counterintuitive often depends a lot on your background. I wouldn't say
never use them, but keep in mind that they are Conversion directives NOT
Cast directives, and conversion can mean all kinds of things.

If you don't want the VB-style behavior, stick to directCast and
System.Convert.
Jun 14 '06 #6
Mike,

Did you ever tried this one

\\\
Dim x as Integer = 2\3 'this is the integer divide
///

Cor

"Mike S" <mg******@netscape.net> schreef in bericht
news:11********************@c74g2000cwc.googlegrou ps.com...
Does anyone know the logic behind why in VB.NET the result of a
floating-point division ('/') is -rounded- on being converted to an
integer type, such as with statements like

Dim x As Integer = 2/3 'after assignment, x is 1, whereas a sane person
would say it should be 0

Does Microsoft have a reason for this design decision? I understand
that this type of rounding can reduce the overall error in long
computation chains by reducing the amount of error that accumulates
from ignoring the fractional part of intermediate results, but why
specifically does VB.NET do this? It seems very unnatural IMO; I can't
think of any other programming language that does this. It would make
much more sense if VB.NET performed floating-point to integer
conversions by simply dropping everything after the decimal. It makes
even less sense to have to use the integer division ('\') operator when
you need to make it explicit that you -don't- want it to perform
rounding. On that note, I think they got the '/' and '\' syntax
backwards. IMHO...

The '/' operator (what is currently
floating-point-division-with-rounding-on-conversion-to-integer) should
behave similar to how the '/' operator behaves in most other
programming languages: the division should be performed in
floating-point; if the result is then converted to an integer, the
fractional part should simply be thrown out without any rounding.

The '\' operator (so-called "integer division") should do what '/'
currently does in VB.NET. That is, it should perform the division and
then round up if the fractional part is greater than or equal to 0.5.

Think about it. Most programming languages only have one division
operator, which is usually written with '/' by convention. And by
convention, '/' in most programming languages means what '\' (integer
division) means in VB.NET. VB.NET is completely upside-down. Sometimes
I get the feeling that Microsoft intentionally goes out of its way to
avoid following conventions or precedent, or anything that might be
considered 'normal.' ;-)

That's my rant. I'm interested to see what everyone else thinks of all
this, and if anyone indeed knows why Microsoft chose to do division
this way.

--
Mike S

Jun 15 '06 #7
david wrote:
Dim j as Integer = 2
Dim i As Integer = CInt(j/3)

i will now be 0, as most non-VB.Net programmers probably expect, while
CInt(2/3) returns 1.
The latter is evaluated at compile-time, like "abc" & "def" would be
evaluated at compile-time. Blame the compiler, but if you explicitly
want zero, use zero.

Mike S wrote: The '\' operator (so-called "integer division") should do what '/'
currently does in VB.NET. That is, it should perform the division and
then round up if the fractional part is greater than or equal to 0.5.
Surely it is best that the \ operator behaves in the standard way?
http://mathworld.wolfram.com/IntegerDivision.html
The moral of the story is to watch out for the CType/CInt/CStr

functions

Um, isn't the moral to read the documentation? :-)

Andrew

Jun 15 '06 #8
On 2006-06-15, Andrew Morton <ak*@in-press.co.uk.invalid> wrote:
david wrote:
The moral of the story is to watch out for the CType/CInt/CStr

functions

Um, isn't the moral to read the documentation? :-)


Well, that's always true, but I don't think anybody really reads the
complete documentation of every single function they call. I'm just
saying that the CType/CInt keywords are a place to be especially careful
about that.

This is especially true since they're billed as Cast Expressions in the
language spec. IMHO, one really doesn't expect a simple cast expression
to do nearly as much work as the CType functions do.
Jun 15 '06 #9
guy
remeber there are 3 ways of converting to integers:- Cint, Int, and Fix
pick the one you want!

from the documentation on Cint

<snip>

When you convert a nonintegral value to an integral type, the integer
conversion functions (CByte, CInt, CLng, CSByte, CShort, CUInt, CULng, and
CUShort) remove the fractional part and round the value to the closest
integer.

If the fractional part is exactly 0.5, the integer conversion functions
round it to the nearest even integer. For example, 0.5 rounds to 0, and 1.5
and 2.5 both round to 2. This is sometimes called banker's rounding, and its
purpose is to compensate for a bias that could accumulate when adding many
such numbers together.

CInt and CLng differ from the Int, Fix Functions (Visual Basic), which
truncate, rather than round, the fractional part of a number. Also, Fix and
Int always return a value of the same data type as you pass in.

</snip>

"david" wrote:
On 2006-06-15, Andrew Morton <ak*@in-press.co.uk.invalid> wrote:
david wrote:
The moral of the story is to watch out for the CType/CInt/CStr

functions

Um, isn't the moral to read the documentation? :-)


Well, that's always true, but I don't think anybody really reads the
complete documentation of every single function they call. I'm just
saying that the CType/CInt keywords are a place to be especially careful
about that.

This is especially true since they're billed as Cast Expressions in the
language spec. IMHO, one really doesn't expect a simple cast expression
to do nearly as much work as the CType functions do.

Jun 15 '06 #10
guy wrote:
remeber there are 3 ways of converting to integers:- Cint, Int, and Fix
Int and Fix doesn't convert.

There is also the Math.Round method, that offers more options than Int
and Fix. (It doesn't convert either.)
pick the one you want!

from the documentation on Cint

<snip>

When you convert a nonintegral value to an integral type, the integer
conversion functions (CByte, CInt, CLng, CSByte, CShort, CUInt, CULng, and
CUShort) remove the fractional part and round the value to the closest
integer.

If the fractional part is exactly 0.5, the integer conversion functions
round it to the nearest even integer. For example, 0.5 rounds to 0, and 1.5
and 2.5 both round to 2. This is sometimes called banker's rounding, and its
purpose is to compensate for a bias that could accumulate when adding many
such numbers together.

CInt and CLng differ from the Int, Fix Functions (Visual Basic), which
truncate, rather than round, the fractional part of a number. Also, Fix and
Int always return a value of the same data type as you pass in.

</snip>

"david" wrote:
On 2006-06-15, Andrew Morton <ak*@in-press.co.uk.invalid> wrote:
david wrote:
The moral of the story is to watch out for the CType/CInt/CStr
functions

Um, isn't the moral to read the documentation? :-)

Well, that's always true, but I don't think anybody really reads the
complete documentation of every single function they call. I'm just
saying that the CType/CInt keywords are a place to be especially careful
about that.

This is especially true since they're billed as Cast Expressions in the
language spec. IMHO, one really doesn't expect a simple cast expression
to do nearly as much work as the CType functions do.

Jun 15 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

31
by: JS | last post by:
We have the same floating point intensive C++ program that runs on Windows on Intel chip and on Sun Solaris on SPARC chips. The program reads the exactly the same input files on the two platforms....
3
by: Sidney Cadot | last post by:
Hi all, As I understand it, the rounding direction of signed integer division in C is unspecified in C89/C94, and specified to be 'towards-zero' in C99. I need division 'towards -infinity'...
2
by: Nicolas | last post by:
Why does for the same code I got different result the VB code gave me what I want why not the csharp? Thank you for your help... CSHARP CODE int sx, sy; double sdegrees; sdegrees = (90 -...
11
by: JohnR | last post by:
I'm trying to find a way to create a variable of a given type at runtime where I won't know the type until it actually executes. For example, dim x as object = "hi" x is declared as an object...
28
by: anonymous | last post by:
I have couple of questions related to array addresses. As they belong to the same block, I am putting them here in one single post. I hope nobody minds: char array; int address; Questions...
94
by: krypto.wizard | last post by:
Last month I appeared for an interview with EA sports and they asked me this question. How would you divide a number by 7 without using division operator ? I did by doing a subtraction and...
5
by: David Lozzi | last post by:
Howdy, I feel quite embarrased asking this question, but for the life of me i can't figure this out. I haven't run a debug, but I think what is happening is that i'm doing some division and its...
6
by: Christopher Key | last post by:
Hello, Could anyone tell me what the various C standards say on the subject of rounding during signed integer division. On my system, it always rounds towards 0: printf("%d", 3/2); // 1...
9
by: Elroy Flynn | last post by:
Decimal a = 42.485M; Decimal b = 48M; Decimal c = a / b; Console.WriteLine(c.ToString()); gives the result 0.8851041666666666666666666667 The correct, exact answer is .885. I know that...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.