12,349,228 members (60,556 online)
Technical Blog
Add your own
alternative version

33K views
19 bookmarked
Posted

# Rounding Floating-Point Numbers Up or Down in .NET

, 18 May 2011 CPOL
 Rate this:
Please Sign up or sign in to vote.
Rounding Floating-Point Numbers Up or Down in .NET

## Introduction

Yesterday, I needed to be able not only to round a floating-point number to a certain number of decimal places, but also control the direction the rounding (i.e.: always force it to round down).

Not a problem, I thought. There will be a method on the `System.Math` class that will let me do just that. How wrong can you be?? My first port of call was the `Math.Round()` method, but whilst you can specify the number of decimal places with this method, you cannot force it to always round either up or down. Next, I looked at `Math.Floor()` and `Math.Ceiling()` methods. These, however, will only round to the nearest integer.

There was nothing else for it, but to roll my own.

## The Solution

The code for my solution is as follows:

```// C#
public static class EnhancedMath
{
private delegate double RoundingFunction(double value);

private enum RoundingDirection { Up, Down }

public static double RoundUp(double value, int precision)
{
return Round(value, precision, RoundingDirection.Up);
}

public static double RoundDown(double value, int precision)
{
return Round(value, precision, RoundingDirection.Down);
}

private static double Round(double value, int precision,
RoundingDirection roundingDirection)
{
RoundingFunction roundingFunction;
if (roundingDirection == RoundingDirection.Up)
roundingFunction = Math.Ceiling;
else
roundingFunction = Math.Floor;
value *= Math.Pow(10, precision);
value = roundingFunction(value);
return value * Math.Pow(10, -1 * precision);
}
}```
```' Visual Basic
Public Module EnhancedMath

Private Delegate Function RoundingFunction(ByVal value As Double) As Double

Private Enum RoundingDirection
Up
Down
End Enum

Public Function RoundUp(ByVal value As Double, ByVal precision As Integer) As Double
Return Round(value, precision, RoundingDirection.Up)
End Function

Public Function RoundDown(ByVal value As Double, ByVal precision As Integer) _
As Double
Return Round(value, precision, RoundingDirection.Down)
End Function

Private Function Round(ByVal value As Double, ByVal precision As Integer, _
ByVal roundingDirection As RoundingDirection) As Double
Dim roundingFunction As RoundingFunction
If roundingDirection = RoundingDireciton.Up Then
roundingFunction = AddressOf Math.Ceiling
Else
roundingFunction = AddressOf Math.Floor
End If
value = value * Math.Pow(10, precision)
value = roundingFunction(value)
Return value * Math.Pow(10, -1 * precision)
End Function

End Module```

The rounding algorithm is quite simple: Firstly, we shift all the digits we are interested in keeping, to the left of the decimal point. We then either call `Math.Floor()` or `Math.Ceiling()` on the result depending on whether we are rounding down or up respectively. Finally, we shift our digits back to the right of the decimal point and return the value.

The method handles values of type `Double`. You can always add your own overloads to handle values of other types (e.g.: `Decimal`).

## Some Examples

Here are some examples of our code in action:

```// C#
static void Main(string[] args)
{
Console.WriteLine(EnhancedMath.RoundUp(3.141592654, 2)); // Result: 3.15
Console.WriteLine(EnhancedMath.RoundUp(3.141592654, 3)); // Result: 3.142
Console.WriteLine(EnhancedMath.RoundDown(3.141592654, 2)); // Result: 3.14
Console.WriteLine(EnhancedMath.RoundDown(3.141592654, 3)); // Result: 3.141
Console.Read();
}```
```' Visual Basic
Sub Main(ByVal args() As String)
Console.WriteLine(EnhancedMath.RoundUp(3.141592654, 2)) ' Result: 3.15
Console.WriteLine(EnhancedMath.RoundUp(3.141592654, 3)) ' Result: 3.142
Console.WriteLine(EnhancedMath.RoundDown(3.141592654, 2)) ' Result: 3.14
Console.WriteLine(EnhancedMath.RoundDown(3.141592654, 3)) ' Result: 3.141
Console.Read()
End Sub```

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Web Developer United Kingdom
No Biography provided

## Comments and Discussions

 First Prev Next
 BE AWARE Member 95725944-Nov-12 23:54 Member 9572594 4-Nov-12 23:54
 My vote of 5 Brad16023-Apr-12 18:58 Brad1602 3-Apr-12 18:58
 My vote of 5 Ant21007-Jun-11 8:34 Ant2100 7-Jun-11 8:34
 Rounding modes supercat919-May-11 5:46 supercat9 19-May-11 5:46
 My vote of 5 T_uRRiCA_N12-May-11 19:49 T_uRRiCA_N 12-May-11 19:49
 Re: My vote of 5 MBigglesworth7918-May-11 13:19 MBigglesworth79 18-May-11 13:19
 My vote of 5 Avijit Jana10-May-11 8:38 Avijit Jana 10-May-11 8:38
 5 but for a different topic! cjb1108-May-11 21:27 cjb110 8-May-11 21:27
 Re: 5 but for a different topic! MBigglesworth799-May-11 0:05 MBigglesworth79 9-May-11 0:05
 Last Visit: 31-Dec-99 18:00     Last Update: 24-Jun-16 22:32 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160621.1 | Last Updated 18 May 2011
Article Copyright 2011 by MBigglesworth79
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid