Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Strange round behaviour?

TedTed Member Posts: 112
round(12.5) should return 13, not 12, yes???

round (12.51) returns 13, so - what's happening here???

And I get the same error(??) with cint(12.5).. which also should return 13, not 12 (cint(12.51) returns 13) - if I've not forgotten all I've learnt at school many years ago..




«13

Comments

  • JonathanJonathan Member Posts: 2,914
    : round(12.5) should return 13, not 12, yes???
    :
    : round (12.51) returns 13, so - what's happening here???
    :
    : And I get the same error(??) with cint(12.5).. which also should
    : return 13, not 12 (cint(12.51) returns 13) - if I've not forgotten
    : all I've learnt at school many years ago..
    :
    School wasn't so many years ago for me, but you've remembered correctly. 12.5 should round up. VB has it wrong. D'oh.

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • TedTed Member Posts: 112
    Thanx!
    So then I have to use something like this in stead..?

    Function rund%(ByVal i As Double)
    Dim des As Double
    des = i - Int(i)
    If des >= 0.5 Then
    rund = Int(i) + 1
    Else
    rund = Int(i)
    End If
    End Function

    OK for me, but it seems strange that it seems to be no litterature around this behaviour on the net. This should be regarded as a serious error in VB, if I (and you) are right, I suppose..





    : : round(12.5) should return 13, not 12, yes???
    : :
    : : round (12.51) returns 13, so - what's happening here???
    : :
    : : And I get the same error(??) with cint(12.5).. which also should
    : : return 13, not 12 (cint(12.51) returns 13) - if I've not forgotten
    : : all I've learnt at school many years ago..
    : :
    : School wasn't so many years ago for me, but you've remembered correctly. 12.5 should round up. VB has it wrong. D'oh.
    :
    : Jonathan
    :
    : ###
    : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    :
    :

  • JonathanJonathan Member Posts: 2,914
    : Thanx!
    : So then I have to use something like this in stead..?
    :
    : Function rund%(ByVal i As Double)
    : Dim des As Double
    : des = i - Int(i)
    : If des >= 0.5 Then
    : rund = Int(i) + 1
    : Else
    : rund = Int(i)
    : End If
    : End Function
    :
    Yeah, for the subset of Round() functionality you want. Remember it has an optional second argument, but if you don't need that, don't worry.

    : OK for me, but it seems strange that it seems to be no litterature
    : around this behaviour on the net. This should be regarded as a
    : serious error in VB, if I (and you) are right, I suppose..
    :
    I'd not noticed it until you mentioned it, but everything I've ever been taught says 0.5 rounds up, and I'm onto degree level stuff. Then, once you reach degree level maths you don't really have numbers any more, just letters, half of which are Greek, and weird symbols. :-)

    The MSDN doesn't document a value at which it decides to round up or down. Sounds like someone in Redmond forget their = in their >= conditional when implementing the VB runtime library, or some people have a different opinion about rounding to you and I. I'd really love to hear their argument.

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • KDivad LeahcimKDivad Leahcim Member Posts: 3,948
    Seems like Basic's rounding has always been messed up...

    I think CInt/CByte/CLng will drop the fractional portion, not round.

    Try this:

    [code]CInt(Num + 0.5)
    [/code]

    : : Thanx!
    : : So then I have to use something like this in stead..?
    : :
    : : Function rund%(ByVal i As Double)
    : : Dim des As Double
    : : des = i - Int(i)
    : : If des >= 0.5 Then
    : : rund = Int(i) + 1
    : : Else
    : : rund = Int(i)
    : : End If
    : : End Function
    : :
    : Yeah, for the subset of Round() functionality you want. Remember it has an optional second argument, but if you don't need that, don't worry.
    :
    : : OK for me, but it seems strange that it seems to be no litterature
    : : around this behaviour on the net. This should be regarded as a
    : : serious error in VB, if I (and you) are right, I suppose..
    : :
    : I'd not noticed it until you mentioned it, but everything I've ever been taught says 0.5 rounds up, and I'm onto degree level stuff. Then, once you reach degree level maths you don't really have numbers any more, just letters, half of which are Greek, and weird symbols. :-)
    :
    : The MSDN doesn't document a value at which it decides to round up or down. Sounds like someone in Redmond forget their = in their >= conditional when implementing the VB runtime library, or some people have a different opinion about rounding to you and I. I'd really love to hear their argument.
    :
    : Jonathan
    :
    : ###
    : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    :
    :

  • righardtrighardt Member Posts: 8
    Conversion, Rounding, and Truncation
    When you convert a decimal value to an integer value, VBA rounds the number to an integer value. How it rounds depends on the value of the digit immediately to the right of the decimal place—digits less than 5 are rounded down, while digits greater than 5 are rounded up. If the digit is 5, then it's rounded down if the digit immediately to the left of the decimal place is even, and up if it's odd. When the digit to be rounded is a 5, the result is always an even integer.

    For example, running the following line of code from the Immediate window prints "8," because VBA rounds down when the number immediately to the left of the decimal is even:

    ? CLng(8.5)

    However, this code prints "10," because 9 is odd:

    ? CLng(9.5)

    If you want to discard the decimal portion of a number, and return the integer portion, you can use either the Int or Fix function. These functions simply truncate without rounding. For example, Int(8.5) returns 8, and Int(9.5) returns 9. The Int and Fix functions behave identically unless you're working with negative numbers. The Int function rounds to the lower negative integer, while the Fix function rounds to the higher one.

    For example, the following code evaluates to "-8":

    ? Fix(-8.2)

    Using the Int function, on the other hand, yields "-9":

    ? Int(-8.2)

    Note The Int and Fix functions always return a Double value. You may want to convert the result to a Long value before performing further operations with it.

    VBA includes a new rounding function called Round, which you can use to round a floating-point or fixed-point decimal to a specified number of places. For example, the following code rounds the number 1.2345 to 1.234:

    ? Round(1.2345, 3)

    Although the Round function is useful for returning a number with a specified number of decimal places, you can't always predict how it will round when the rounding digit is a 5. How VBA rounds a number depends on the internal binary representation of that number. If you want to write a rounding function that will round decimal values according to predictable rules, you should write your own. For more information, see the Visual Basic Language Developer's Handbook by Ken Getz and Mike Gilbert (Sybex, 1999

  • Gurpreet2311Gurpreet2311 Member Posts: 326
    Hi Guys,
    Actually Its all going in the wrong way.
    VB is doing it right but you are making it a little complex.

    It works as this in Pure mathematics.

    Suppose we have to round off a digit to two decimal places
    ie no1.xxxxxxx to no1.xx

    Now the limiting point here is 5.

    It means if the digit after the precision digit is 5 or big ie 5,6,7,8,9

    Then we have to increment the last decimal digit by 1

    Otherwise leave it as it is

    For Example

    [code]
    If we have to round a no upto two decimal places like :

    145.456789

    the ans will be 145.46 as the third place from decimal is 6 and accordingly second digit from decimal should be raised by 1 ie .46 instead of .45


    All these no will produce 145.46

    145.455789
    145.456789
    145.457789
    145.458789
    145.459789

    But all of these no will produce 145.45

    145.450789
    145.451789
    145.452789
    145.453789
    145.454789


    [/code]

    So if the no is 5 or above the no will be raised and if its 0 to 4 the no will not be touched.

    In most Engineering exams it is specified to round off the answers to 3 or 4 decimal places. So we are used to that thing.

    VB is right (Mostly to be exact)

    Hope it Helps !!

    [b]Regards
    Er. [blue]Gurpreet Singh [/blue](B.E [blue]Mech.)[/blue][/b]
    [hr]



  • ZantosZantos Member Posts: 139
    you're all looking at this the wrong way...too much code involved. Do this:
    [code]
    Dim nValue As Long
    nValue = 8.5 '// or whatever the value/expression

    '// this will raise the value + 0.5, enough to always round up
    '// but not enough to make it go one higher.
    nValue = Round(nValue, 1) + .5
    [/code]

    If nValue = 8.0 then it will try and round 8.5, thus resulting in 8.
    If nValue = 8.5 then it will try and round 9.0, thus resulting in 9.
    If nValue = 8.6 then it will try and round 9.1, thus resulting in 9.
    In nValue = 8.9 then it will try and round 9.4, thus resulting in 9.

    As long as you add on the + .5 it will always round up.
    [code]<%
    '// Programmed By: Zantos
    '// VisualProgramming.NET
    '// http://vp.funurl.com/
    '// [email protected]
    %>[/code]

  • TedTed Member Posts: 112
    Nope, CInt(Num + 0.5) does not work:
    CInt(1.5 + 0.5) returns 2, not 1

    This seems to work ok:

    Function RightRound(ByVal i As Double) As Long
    RightRound = Round(i, 1) + 0.5
    End Function



    Ted



    : Seems like Basic's rounding has always been messed up...
    :
    : I think CInt/CByte/CLng will drop the fractional portion, not round.
    :
    : Try this:
    :
    : [code]CInt(Num + 0.5)
    : [/code]
    :
    : : : Thanx!
    : : : So then I have to use something like this in stead..?
    : : :
    : : : Function rund%(ByVal i As Double)
    : : : Dim des As Double
    : : : des = i - Int(i)
    : : : If des >= 0.5 Then
    : : : rund = Int(i) + 1
    : : : Else
    : : : rund = Int(i)
    : : : End If
    : : : End Function
    : : :
    : : Yeah, for the subset of Round() functionality you want. Remember it has an optional second argument, but if you don't need that, don't worry.
    : :
    : : : OK for me, but it seems strange that it seems to be no litterature
    : : : around this behaviour on the net. This should be regarded as a
    : : : serious error in VB, if I (and you) are right, I suppose..
    : : :
    : : I'd not noticed it until you mentioned it, but everything I've ever been taught says 0.5 rounds up, and I'm onto degree level stuff. Then, once you reach degree level maths you don't really have numbers any more, just letters, half of which are Greek, and weird symbols. :-)
    : :
    : : The MSDN doesn't document a value at which it decides to round up or down. Sounds like someone in Redmond forget their = in their >= conditional when implementing the VB runtime library, or some people have a different opinion about rounding to you and I. I'd really love to hear their argument.
    : :
    : : Jonathan
    : :
    : : ###
    : : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    : :
    : :
    :
    :

  • TedTed Member Posts: 112
    Well, I'm not sure if I understand what you mean here..
    Only the first digit after the potential rounding digit is intersting here: if it is 5 or higher, the potential rounding digit should go up by one, if it is 4 or lower it should be left as it is:

    VB does not behave like that, producing unpredictible results:

    ?round (1.5)
    2 (ok, as it should)


    ?round (12.5)
    12 (not 13, as it should)

    If you really think this is not an error, I'm very interested in an explanation. (Maybe that's what you tried to do in your article, but I didn't get it, I think..) :(=

    Ted


    : Hi Guys,
    : Actually Its all going in the wrong way.
    : VB is doing it right but you are making it a little complex.
    :
    : It works as this in Pure mathematics.
    :
    : Suppose we have to round off a digit to two decimal places
    : ie no1.xxxxxxx to no1.xx
    :
    : Now the limiting point here is 5.
    :
    : It means if the digit after the precision digit is 5 or big ie 5,6,7,8,9
    :
    : Then we have to increment the last decimal digit by 1
    :
    : Otherwise leave it as it is
    :
    : For Example
    :
    : [code]
    : If we have to round a no upto two decimal places like :
    :
    : 145.456789
    :
    : the ans will be 145.46 as the third place from decimal is 6 and accordingly second digit from decimal should be raised by 1 ie .46 instead of .45
    :
    :
    : All these no will produce 145.46
    :
    : 145.455789
    : 145.456789
    : 145.457789
    : 145.458789
    : 145.459789
    :
    : But all of these no will produce 145.45
    :
    : 145.450789
    : 145.451789
    : 145.452789
    : 145.453789
    : 145.454789
    :
    :
    : [/code]
    :
    : So if the no is 5 or above the no will be raised and if its 0 to 4 the no will not be touched.
    :
    : In most Engineering exams it is specified to round off the answers to 3 or 4 decimal places. So we are used to that thing.
    :
    : VB is right (Mostly to be exact)
    :
    : Hope it Helps !!
    :
    : [b]Regards
    : Er. [blue]Gurpreet Singh [/blue](B.E [blue]Mech.)[/blue][/b]
    : [hr]
    :
    :
    :
    :

  • Gurpreet2311Gurpreet2311 Member Posts: 326
    : Well, I'm not sure if I understand what you mean here..
    : Only the first digit after the potential rounding digit is intersting here: if it is 5 or higher, the potential rounding digit should go up by one, if it is 4 or lower it should be left as it is:

    [blue]
    Yes It is that way. But there is also one point which I failed to
    tell earlier which concerns with 5 as the last digit.

    [/blue]

    :
    : VB does not behave like that, producing unpredictible results:
    :
    : ?round (1.5)
    : 2 (ok, as it should)
    :
    :
    : ?round (12.5)
    : 12 (not 13, as it should)
    :

    [blue]

    VB is correct, I think I would have explained better in the first place.


    Well It goes like this :

    If the last digit is 6 or above the no should be raised by 1.

    Now If the last digit is 5 then we have to look at the preciding digit.

    If the preciding digit is an even ie 0,2,4,6,8 then the digit will NOT be raised by 1.

    But If the preciding digit on left of last digit (ie 5) is an
    odd one ie 1,3,5,7,9 then the value is raised by 1.

    For example if we take case of 12.5
    The last digit is 5
    The preciding digit left to it is 2 which is even no
    According to rule it will not be raised and will round off at 12

    But if the no's are like
    13.5,15.5,17.5,19.5
    then as You can see the left digit are odd
    And according to rule it will be raised by 1 producing round off at
    14,16,18 and 20 respectively.

    [code]

    So The thing is that


    If the last digit at the accuracy level (ie If the accuracy wanted is
    2 digit from decimal then the third digit from decimal) is 6,7,8,9 then the digit immediately left to it will be raised by 1.


    If the last digit at the accuracy level (ie If the accuracy wanted is
    2 digit from decimal then the third digit from decimal) is 1,2,3,4 then the digit immediately left to it will NOT be changed.


    If the last digit at the accuracy level (ie If the accuracy wanted is
    2 digit from decimal then the third digit from decimal) is 5 then the digit immediately left to it will be considered.
    If it is even as 0,2,4,6,8 then it will NOT be Raised.
    But if it is odd ie 1,3,5,7,9 then it will be Raised by 1.


    [/code]


    [/blue]
    [b]Regards
    Er. [blue]Gurpreet Singh [/blue](B.E [blue]Mech.)[/blue][/b]
    [hr]



«13
Sign In or Register to comment.