Custom decimal round

L

Luigi

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?

Thanks in advance.
 
M

Marc Gravell

How about something cheeky like:

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

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

Marc
 
J

Jon Skeet [C# MVP]

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
 
S

SLL

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?

Thanks in advance.

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

Marc Gravell

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
 
L

Luigi

Thank you all very much.
I'll try this one method:

decimal x = 1.51m;

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

Luigi
 
M

Michel Walsh

Note that this is called the banker rounding: if, for x a positive integer,
x + .5 is always rounded to (x+1), the banker ends up loosing money. So,
1.5 is rounded to 2, that is, upward, the banker lost is 0.5; while 2.5 is
*also* rounded to 2, that is, downward, and the banker get a profit of 0.5
in that case.

Statistically, the banker should be not loosing, neither winning (assuming
the integer part has no bias toward odd or toward even numbers) with that
way to round. You probably already know it, but just in case someone reading
this thread was not.

Vanderghast, Access MVP
 
M

Marc Gravell

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
 
M

Michel Walsh

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
 
L

Luigi

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
 
M

Marc Gravell

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
 
L

Luigi

Marc Gravell said:
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
 
M

Michel Walsh

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
 
G

Ganesh Pai

Have u tried using Decimal.Round method?

When i tried using it, it gives me the following result

Decimal.Round(x) Returns for
x = 1.49 --> 1
x = 1.5 --> 1
x = 1.5 + .000000000001 --> 2

Can u pls try this?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top