Why not do it with simple multiplication by powers of 10, this effectively shift the decimal point where you can call Math.Ceiling to round the number up. Divide by the same power of 10 to put the decimal point back where it was.
Using decimal.ToString()
to "get around" the problems of floating point precision see this blog post for more information
var values = new[] { 1.527f, 1.53f, 1.6f, -1.527f };
for (var i = 0; i < values.Length; i++)
{
var val = (decimal)values[i];
var precision = (decimal.GetBits(val)[3] >> 16 & 0xff) - 1;
var power = (decimal)Math.Pow(10, precision);
if (val < 0)
val = Math.Floor(val * power) / power;
else
val = Math.Ceiling(val * power) / power;
Console.WriteLine(val);
}
Outputs
1.53
1.6
2
-1.53
NOTE Math.Pow
and Math.Ceiling
are operations on double
, hence the cast to double
from float
UPDATE Figures out how much decimal places it needs rounding to and uses decimal which "gets around" the issues with floating point precision.
UPDATE 2 Uses decimal.GetBytes
to get the number's precision rather than doing the rather cumbersome culture invariant ToString().Split
yada yada yada.
UPDATE 3 Rounds away from zero for negative numbers and added bitwise & 0xff
to strip off sign bit.