Rounding Problem

brspnr
01-12-2005, 03:48 PM
i couldnt use Round function here how can i round these value?

dim i as decimal
i=50,265
dim j as decimal=i.round(i,2)


it says j=50,26
but i want to get: j=50,27
are there any methods which i can use?
thanx.

AtmaWeapon
01-12-2005, 04:11 PM
Reading the documentation for Decimal.Round (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdecimalclassroundtopic.asp) reveals:When d is exactly halfway between two rounded values, the result is the rounded value that has an even digit in the far right decimal position. For example, when rounded to two decimals, the value 2.345 becomes 2.34 and the value 2.355 becomes 2.36. This process is known as rounding toward even, or rounding to nearest.

If you don't like this behavior, the unfortunate truth would seem to be that you would have to write your own code to do the rounding.

That rounding behavior is quite odd (no pun intended). I wonder why Microsoft chose iit rather than rounding to the next largest number?

the12thplaya
01-12-2005, 04:17 PM
How about converting the decimal to string, then search the string for a decimal point, if found and length after that is greater then 3 and last digit equals 5, remove the last 5, increase the number before that by one and convert the string back to decimal?

Sorry can't supply code, but that's what I'd try if I was encountering the same problem. Wouldn't be much code if it works I don't believe

EagleEye1975
01-15-2005, 03:37 PM
I just had this problem and found the fix to it...

First of all, let me just say... :huh: :huh: :huh: WHAT KIND OF MONKEY-******* ON CRACK ROUNDS THINGS THIS WAY?

Okay, now that that's out of my system...

The resolution is to take your number, add .5 to it, and floor the value.

Dim I as Double = 2061
Dim EndNum as Double

EndNum = math.round(I / 2) ' Produces 1030
EndNum = math.floor((I / 2) + 0.5) ' Produces 1031
I = 2063
EndNum = math.round(I / 2) ' Produces 1032
EndNum = math.floor((I / 2) + 0.5) ' Produces 1032

Notice how we can't get a 1031 result with the ROUND function evaluating a .5 decimal?

Others would say "add a miniscule value to it, like .0000001, then round it"...

But what happens if your number is 3.4999999? :)

Want an even BIGGER mind ****?

Int16, Int32, and Int64 types are all "zero decimal precision"... right?

So what do you think happens when you do the following...

Dim I as Int32 = 7

I / 2 = 4 ' this is correct
I = 9
I / 2 = 4 ' Woah, *** man!

The lesson: Dividing values that are stored in variables without decimal precision will cause rounding to go to the nearest even.

Iceplug
01-16-2005, 07:49 AM
Well, (aside from all of those obscenities) the rounding scheme is used so that if you were rounding a lot of ##.5 values, you'd get a closer result by rounding to the closest even number instead of rounding it up to the next integer.
But so far it has caused more problems than it solves.

However, 7 / 2 returns 3.5, unless you do not have Option Strict on, in which case it (the implicit operation conversion) changes this value so that it fits in whatever variable you declare it within.
Doing division with integers is better with the \ (backslash), which does integer division with its two operands.
Then, 7 \ 2 returns 3, and 9 \ 2 returns 4.

So, the lesson is more like 'using a round function causes the number to go to the nearest even'.

And P.S. while using a string is a solution, note that numbers are typically faster than strings.

EagleEye1975
01-17-2005, 10:33 PM
Well, (aside from all of those obscenities) the rounding scheme is used so that if you were rounding a lot of ##.5 values, you'd get a closer result by rounding to the closest even number instead of rounding it up to the next integer.
But so far it has caused more problems than it solves.

Yeah, I realize this... my problem was that this was for a "serial number to activation code" algorithm, so I had to have predictable rounding. And people that purchased my program would get their activation code from a web site, and PHP's round function rounds up from .5... so people were getting the right code, but my program was expecting the wrong one because of this little tidbit.

I wasn't using the Round function in VB, though... I was just doing division and placing the result in variables declared as "Long" (Int32), so it would "auto-round" the result because that type has no decimal precision... which was fine, because I only cared about the whole number (I didn't want activation codes with decimals in them). Little did I know, it was rounding to even. :( I had overflow problems with some of my program's activation codes anyway (they were getting rather large), so I switched to Double, and did the "add .5, floor" method on it... 2 birds, 1 stone. :)

However, 7 / 2 returns 3.5, unless you do not have Option Strict on, in which case it (the implicit operation conversion) changes this value so that it fits in whatever variable you declare it within.
Doing division with integers is better with the \ (backslash), which does integer division with its two operands.
Then, 7 \ 2 returns 3, and 9 \ 2 returns 4.

So, the lesson is more like 'using a round function causes the number to go to the nearest even'.

Heh... That's what I was saying, and it's good to know... but also, since I was using a no-decimal-precision variable as a result holder, it was automatically doing that rounding... which is also good to know.

And P.S. while using a string is a solution, note that numbers are typically faster than strings.

I'd never even consider doing a type conversion to string for something like this... seems kinda useless and wasteful.

Mike Rosenblum
01-18-2005, 12:09 AM
Don't use Strings...

Here's my stab at a solution: Overloads Shared Function RoundArith(ByVal number As Double) As Double
' Uses "Arithmetic Rounding" as we are taught in school, which
' is the same as is used by Excel.WorksheetFunctions.Round(). It will
' always round up for a 0.5 digit situation.
'
' This is in contrast to the System.Math.Round() function,
' which uses "Statistical Rounding", which breaks on 0.5 depending
' on if the resultant digit is odd or even parity.
'
' If the 'numDigitsAfterDecimal' parameter is not provided, then it's
' default value used is zero (0).
'
' Examples:
'
' (1) RoundArith(9.4999) ' Returns 9
' (2) RoundArith(9.4999, 2) ' Returns 9.50
' (3) RoundArith(-9.4999, 2) ' Returns -9.50
'
' -- Mike_R 2005 0118

Return RoundArith(number, numDigitsAfterDecimal:=0)
End Function

Overloads Shared Function RoundArith(ByVal number As Double, _
ByVal numDigitsAfterDecimal As Integer) As Double
Dim multiplier As Double = 10 ^ numDigitsAfterDecimal
Dim sgn As Double = System.Math.Sign(number)
RoundArith = System.Math.Floor(sgn * number * multiplier + 0.5) / multiplier * sgn
End Function I don't know if this is the fastest possible, but it will be lightening compared to anything using Strings.

The use of the 'sgn' parameter is a little weird looking, but the other way to go is to flip-flop the use of Floor vs. Ceiling as well as the value of the +0.5 to be -0.5. I found the 'sgn' manipulation to be a little easier. Note that it's used twice, so that it does "cancel out".

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum