4

If I do Math.Round(95.55555555,2) in VB.NET, the result is 95.56, but I want it the result the be 95.55. Is there a way to do this in VB.NET? I guess I just want to keep the decimal places, but not round them

Xaisoft
  • 45,655
  • 87
  • 279
  • 432
  • 1
    The question is: what is your precise condition to round it to 95.55 rather than 95.56? If it's only a question of limit at which point to round to the lesser rather than the greater, it's trivial to write your own rounding function, I think. I will not try it, as I'm not really fond of VB... :-) But be careful with border effects... – Alexis Dufrenoy Mar 30 '11 at 16:02
  • 1
    Would you want `Math.Round(95.55666666,2)` to round to 95.55 or 95.56? Are you actually rounding or just cutting it off after x precision? – Aaron W. Mar 30 '11 at 16:05
  • Sounds like you're not actually wanting a round, but rather a truncate. – p.campbell Mar 30 '11 at 16:07
  • Yes, I basically want to truncate, but keep two decimal places. – Xaisoft Mar 30 '11 at 16:08

6 Answers6

7

Looks like Math.Truncate(95.5555555 * 100) / 100.
See Truncate Decimal number not Round Off

Community
  • 1
  • 1
Michael Blake
  • 2,068
  • 2
  • 18
  • 31
5

Try using Math.Floor(95.55555555 * 100) / 100

Or, if you want to round to a specific number of decimals:

Public Function RoundDown(ByVal value As Double, ByVal decimalPlaces As Integer) As Double
    If (decimalPlaces < 1) Then
        Throw New ArgumentException("Invalid decimalPlaces: less than 1")
    EndIf

    Dim factor As Integer = 10 ^ decimalPlaces
    Return Math.Floor(value * factor) / factor
End Sub
Rob
  • 5,223
  • 5
  • 41
  • 62
  • What are you talking about? `Floor(95.5555555... * 100) = 9555`, and `9555/100 = 95.55`. – Rob Mar 30 '11 at 16:09
  • One question I have is what if I wanted to truncate to 3 decimal places, how does that change the Math.Floor or Math.Truncate method. For example, I want 95.5556 to be 95.555. – Xaisoft Mar 30 '11 at 16:22
  • After looking at a similar question, is it just doing something like Math.Floor(value * 1000) / 1000; to keep 3 decimal places. – Xaisoft Mar 30 '11 at 16:26
  • Yep, that's exactly how you would do it for 3 decimal places. – Rob Mar 30 '11 at 17:29
2

There are several ways to do this. One would be to subtract 0.05 from the number then use Math.Round(number, 2). (This works on the same principle as implementing floor and ceiling functions when all you have is round.)

A better way is probably

Math.Truncate(number * 100) / 100

That just multiplies the number by 100 and truncates it, giving you an integer value with the digits you want, then divides by 100 to turn it back to a decimal.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • What is the difference between Math.Floor(number * 100) /100 and Math.Truncate(number * 100) / 100? – Xaisoft Mar 30 '11 at 16:10
  • 1
    Floor is used to round down. Truncate just cuts. Ceiling rounds up – Michael Blake Mar 30 '11 at 16:15
  • 1
    @Xaisoft: Floor always rounds down, so you'll see a difference if your value is negative. – Bill the Lizard Mar 30 '11 at 16:17
  • They are two different operations that return the same result, in this case. `Floor()` returns the closest integer value smaller than the input (but not necessarily `Integer` type), while `Truncate()` chops off everything after the decimal. *They are only different in how they handle negative numbers.* – Rob Mar 30 '11 at 16:17
1

You don't want Math.Round. You want Math.Truncate.

Dim decimalNumber As Double = 95.55555555
Dim truncatedNumber As Double = Math.Truncate(decimalNumber * 100) / 100

Your result will be 95.55.

Geo Ego
  • 1,315
  • 7
  • 27
  • 53
0
Public Function Round(Number As Decimal, places As Integer) As Decimal
    'Convert number to string
    Dim NumberString As String = Number.ToString
    'Check if the number contains a decimal, if not return the number
    If NumberString.IndexOf("."c) = -1 Then Return Number
    'Get the whole number part of the string
    Dim IntegerPart As String = NumberString.Split("."c)(0)
    'Get the Decimal part of the string
    Dim DecimalPart As String = NumberString.Split("."c)(1)
    'If the number is already rounded to n decimal places, then return the number
    If DecimalPart.Length = places Then Return Number
    'Get whichever decimals are being rounded to
    Dim ToPlacePart As String = DecimalPart.Substring(0, places)
    'get the other part that will be compared
    Dim ComparePart As String = DecimalPart.Substring(places)
    'Create a midpoint to compare the compare part to
    Dim ControlMidPoint As Decimal = Decimal.Parse("1" & Replace(Space(ComparePart.Length), Space(1), "0")) / 2
    'Create the base result(Add the integer part to the decimal part that will stay)
    Dim Result As Decimal = Decimal.Parse(IntegerPart & "." & ToPlacePart)
    'Create an increment to add if the comparepart is greater than the mid point(ex 0.001, 0.01, 0.0000001)
    Dim AddNum As Decimal = Decimal.Parse("0." & Replace(Space(ToPlacePart.Count - 1), Space(1), "0") & "1")
    'If the comparepart was equal to or greater than the midpoint, then add the addpart to the base result and return it
    If Decimal.Parse(ComparePart) >= ControlMidPoint Then Return Result + AddNum
    'Just return the base result, because the compare part was smaller than the midpoint
    Return Result
End Function
Paul Ishak
  • 1,093
  • 14
  • 19
0

You can use this:

static double TruncateWithDecimals(double n, int nOfDec)
        {
           return Math.Round(Math.Floor(n * Math.Pow(10, nOfDec)) /  Math.Pow(10, nOfDec), nOfDec);
        }

sorry this is C#, but you can easily guess how to translate in vb I think.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115