Automatic type conversion in Visual Basic 6.0

When we convert float to integer in visual basic 6.0, how does it round the fractional part? I am talking about automatic type conversion.

If we assign as

Dim i as Integer i=5.5 msgbox i 

What will he print? 5 or 6?

I was getting "5" a couple of months ago. Once it started giving me 6! Any idea what is going wrong? Has Microsoft released several fixes to fix something?

Update: 5.5 converts to 6, but from 8.5 to 8!

Update 2: adding CInt doesn't matter. CInt (5.5) gives 6, and Cint (8.5) gives 8 !! Own behavior. I have to try something like sex (x + 0.49);

+4
source share
5 answers

Part of this is in the VB6 help: topic Type Conversion Functions. Unfortunately, this is one of the topics that is not in the VB6 documentation on the MSDN website, but if you installed help with VB6, it will be there.

When the fractional part is 0.5, CInt and CLng , round it to the nearest even number. For example, from 0.5 rounds to 0 and from 1.5 rounds to 2. CInt and CLng differ from Fix and Int functions, which truncate, rather than round, the fractional part of the number. In addition, Fix and Int always return the same type of value as passed.

Implicit type coercion - aka "coercive evil type (PDF)" - from a floating-point number to an integer, uses the same rounding as CInt and CLng . This behavior does not seem to be documented anywhere in the manual.

If you want to round when the fractional part is> 0.5, otherwise an easy way to do this is

  n = Int(x + 0.5) 

And from my head, here is my shorter version of Mike Sporas RoundNumber :), which replaces the VB6 Round feature.

  'Written off the top of my head, seems to work. Public Function RoundNumber(ByVal value As Double, Optional PlacesAfterDecimal As Integer = 0) As Double Dim nMultiplier As Long nMultiplier = 10 ^ PlacesAfterDecimal RoundNumber = Int(0.5 + value / nMultiplier) * CDbl(nMultiplier) End Function 

Output Example:

 Debug.Print RoundNumber(1.6) '2' Debug.Print RoundNumber(-4.8) '-5' Debug.Print RoundNumber(101.7) '102' Debug.Print RoundNumber(12.535, 2) '12.54' 
+7
source

Update: After some Google search, I came across the following article :

This is not a “mistake”, it is the way VB was designed to work. It uses something known as banker rounding, which, if the number ends exactly 5, and you want to round to the position in front of 5, rounds the numbers if the number before the 5th position is even and rounds up otherwise. It should protect against recalculation using rounded numbers, so the answer does not always shift up. For more information on this than you probably want to know, see the link

http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q196652

This explains the (seeming) weird behavior:

 Cint(5.5) 'Should be 6' Cint(8.5) 'Should be 8' 

Old update: Perhaps you should be more explicit: use CInt instead of simply assigning a float to an integer. For instance:

 Dim i as Integer i = CInt(5.5) MsgBox i 
+7
source

The changed behavior sounds alarming, but the correct answer is 6. Scroll down to "Round to even method" on Wikipedia, Rounding for an explanation.

+1
source

As others have already pointed out, the “weird behavior” you see is due to the fact that VB6 uses Rounding Banker when rounding up fractional values.

Update 2: adding CInt does not make a difference. CInt (5.5) gives 6 and Cint (8.5) gives 8!

This is also normal. CInt always rounds before performing the conversion (again using the Banker rounding method).

If you have a number with a fractional part and just want to truncate it (ignore the part after the decimal point), you can use either the Fix or Int function:

 Fix(1.5) = 1 Fix(300.4) = 300 Fix(-12.394) = -12 

Int works just like Fix , except that it rounds negative numbers to the next lower negative number:

 Int(1.5) = 1 Int(300.4) = 300 Int(-12.394) = -13 

If you really want to round the number according to the rules that most people are familiar with, you will have to write your own function to do this. The following is an example of rounding, which is rounded when the fractional part is greater than or equal to 0.5, and rounded otherwise:


EDIT : See MarkJ's answer for a simpler (and probably faster) version of this function.


 ' Rounds value to the specified number of places' ' Probably could be optimized. I just wrote it off the top of my head,' ' but it seems to work.' Public Function RoundNumber(ByVal value As Double, Optional PlacesAfterDecimal As Integer = 0) As Double Dim expandedValue As Double Dim returnValue As Double Dim bRoundUp As Boolean expandedValue = value expandedValue = expandedValue * 10 ^ (PlacesAfterDecimal + 1) expandedValue = Fix(expandedValue) bRoundUp = (Abs(expandedValue) Mod 10) >= 5 If bRoundUp Then expandedValue = (Fix(expandedValue / 10) + Sgn(value)) * 10 Else expandedValue = Fix(expandedValue / 10) * 10 End If returnValue = expandedValue / 10 ^ (PlacesAfterDecimal + 1) RoundNumber = returnValue End Function 

<strong> Examples

 Debug.Print RoundNumber(1.6) '2' Debug.Print RoundNumber(-4.8) '-5' Debug.Print RoundNumber(101.7) '102' Debug.Print RoundNumber(12.535, 2) '12.54' 
+1
source

The VB6 Round () function uses the Banker rounding method . MS KB Article 225330 ( http://support.microsoft.com/kb/225330 ) indirectly talks about this, comparing VBA in the behavior of Office 2000 and Excel and describes it as follows: / p>

When an even integer number ends in .5, Visual Basic rounds the number (down) to the nearest integer. [...] This difference [between VBA and Excel] is only for numbers ending in .5 and is the same with other fractional numbers.

If you need other behavior, I'm afraid you will have to specify it yourself.

0
source

Source: https://habr.com/ru/post/1259592/


All Articles