471,319 Members | 3,253 Online

# Custom decimal round

Hi all,
I need to round a decimal value with a particular rule.
For example:

decimal a = 1.49m -1m
decimal a = 1.5m -1m
decimal a = 1.51m -2m

I've tried Math.Round but with the value 1.5 it returns me 2, which it is
not correct for my business rule.

How can I solve this problem?

--
Luigi

Jul 1 '08 #1
13 4134 On Jul 1, 3:23*pm, Luigi <ciupazNoSpamGra...@inwind.itwrote:
I need to round a decimal value with a particular rule.
For example:

decimal a = 1.49m -1m
decimal a = 1.5m -1m
decimal a = 1.51m -2m

I've tried Math.Round but with the value 1.5 it returns me 2, which it is
not correct for my business rule.

How can I solve this problem?
I'd write a custom rounding method. It's reasonable simple if you have
a very specific requirement. In this case, something like:

public decimal Round (decimal value)
{
decimal floor = Math.Floor(value);
decimal ceiling = Math.Floor(value);
decimal midpoint = (floor+ceiling)/2;
return value <= midpoint ? floor : ceiling;
}

It's possible that there will be some weird problems around the very
largest numbers that decimals can store, but if your application
doesn't use those (and it's unlikely to) then you should be okay.

This is completely untested though - I strongly recommend writing unit
tests for it!

Jon
Jul 1 '08 #2
How about something cheeky like:

decimal a = Math.Ceiling(x-0.5M);

Obviously you'd need to think about -ves etc...

Marc
Jul 1 '08 #3
On Jul 1, 10:23*am, Luigi <ciupazNoSpamGra...@inwind.itwrote:
Hi all,
I need to round a decimal value with a particular rule.
For example:

decimal a = 1.49m -1m
decimal a = 1.5m -1m
decimal a = 1.51m -2m

I've tried Math.Round but with the value 1.5 it returns me 2, which it is
not correct for my business rule.

How can I solve this problem?

--
Luigi
Try multiplying by 10*(number of decimals needed), used math.floor or
math.ceiling, then divide by same number 10*(number of decimals
needed)

Jul 1 '08 #4

Assuming you mean 10 raised-to-the-power-of (number of decimals), the OP
appears to want zero decimals. Taking the cited example 1.51, this would
give 1M, not 2M as desired.

Marc
Jul 1 '08 #5
On Tue, 1 Jul 2008 07:55:38 -0700 (PDT), "Jon Skeet [C# MVP]"
<sk***@pobox.comwrote:
>On Jul 1, 3:23*pm, Luigi <ciupazNoSpamGra...@inwind.itwrote:
>I need to round a decimal value with a particular rule.
For example:

decimal a = 1.49m -1m
decimal a = 1.5m -1m
decimal a = 1.51m -2m

I've tried Math.Round but with the value 1.5 it returns me 2, which it is
not correct for my business rule.

How can I solve this problem?

I'd write a custom rounding method. It's reasonable simple if you have
a very specific requirement. In this case, something like:

public decimal Round (decimal value)
{
decimal floor = Math.Floor(value);
decimal ceiling = Math.Floor(value);
Did you mean "decimal ceiling = Math.Ceiling(value);"? rossum
decimal midpoint = (floor+ceiling)/2;
return value <= midpoint ? floor : ceiling;
}

It's possible that there will be some weird problems around the very
largest numbers that decimals can store, but if your application
doesn't use those (and it's unlikely to) then you should be okay.

This is completely untested though - I strongly recommend writing unit
tests for it!

Jon
Jul 1 '08 #6
rossum <ro******@coldmail.comwrote:

<snip>
decimal ceiling = Math.Floor(value);
Did you mean "decimal ceiling = Math.Ceiling(value);"? rossum
Yup. That's what I get for not testing it...

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 1 '08 #7
Thank you all very much.
I'll try this one method:

decimal x = 1.51m;

decimal a = Math.Ceiling(x - 0.5M);

Luigi
Jul 2 '08 #8
Note that this is called the banker rounding

I'm fairly certain that the original question as posed doesn't relate
to banker's rounding; it is just .5 always rounding down.

Marc
Jul 3 '08 #9
Yes, sorry, I was not clear. The OP want a rounding down at 0.5, but GOT a
banker rounding, with Math.Round(x, 0).

Vanderghast, Access MVP
"Marc Gravell" <ma**********@gmail.comwrote in message
>Note that this is called the banker rounding

I'm fairly certain that the original question as posed doesn't relate
to banker's rounding; it is just .5 always rounding down.

Marc

Jul 3 '08 #10
Another question.
To adhere to these rules when the values are negative:

Criteria to round negative amounts are the following:
-1.5 =- 1
- 1.6 =- 2
-1.4 =- 1
how can I write a method that make this rounding?
Values are decimal.

Thanks.

Luigi

Jul 15 '08 #11
If this follows the same rules as +ve, but negated - then perhaps just
check whether the value is <0, and then:
* negate the value (making it +ve)
* apply the current rounding logic (which works for +ve)
* negate the result (making it -ve)

Marc
Jul 15 '08 #12
"Marc Gravell" wrote:
If this follows the same rules as +ve, but negated - then perhaps just
check whether the value is <0, and then:
* negate the value (making it +ve)
* apply the current rounding logic (which works for +ve)
* negate the result (making it -ve)
I'm using:

decimal a = Math.Ceiling(x-0.5M);

but not works correctly.

-1.6 --1 (and not -2)

L
Jul 15 '08 #13
The ceiling is the first integer greater or equal to its argument.
Technically, -1 is greater than (is to the 'right' of, if you draw the x
axis) -1.6. -2 is smaller, and to the left, of -1,.6.

As suggested by Marc Gravel, you can use:

y = ( x>=0) ? roundingPositiveValue(x) : - roundingPositiveValue( -x )
;

where 'roudingPositiveValue' is your required method.

Vanderghast, Access MVP

"Luigi" <ci****************@inwind.itwrote in message
news:F9**********************************@microsof t.com...
"Marc Gravell" wrote:
>If this follows the same rules as +ve, but negated - then perhaps just
check whether the value is <0, and then:
* negate the value (making it +ve)
* apply the current rounding logic (which works for +ve)
* negate the result (making it -ve)
I'm using:

decimal a = Math.Ceiling(x-0.5M);

but not works correctly.

-1.6 --1 (and not -2)

L

Jul 15 '08 #14

### This discussion thread is closed

Replies have been disabled for this discussion.