C#的最后一位数字始终向上浮动

时间:2018-08-09 09:28:15

标签: c# rounding precision

我想在C#中实现一个函数,该函数采用一个浮点数,并以此输出舍入后的数字(总是向上):

1,527 -> 1,53
1,53 -> 1,6
1,6 -> 2

最简单的方法是什么?

编辑: 为了清除它-我希望它设置2D图形轴的适当最大值,因此如果最大值为1,527,我想对该函数进行几次迭代,直到四舍五入的值大于例如。 10%,因此对于1,527,最大值可能是1,6,因此1,527适合几乎同时使用的图形

4 个答案:

答案 0 :(得分:1)

使用this question's marked answer

static void Main()
{
    Console.WriteLine("DECIMAL");

    decimal dTest = 1.527m;
    var dTest2 = dTest;

    while(dTest2 < dTest*1.1m)
    {
        dTest2 = RoundUp(dTest2);
        Console.WriteLine(dTest2);
    }

    Console.WriteLine("FLOAT");

    float fTest = 1.527f;
    var fTest2 = fTest;

    while(fTest2 < fTest*1.1f)
    {
        fTest2 = RoundUp(fTest2);
        Console.WriteLine(fTest2);
    }
}

static decimal RoundUp(decimal input)
{
    int precision = BitConverter.GetBytes(decimal.GetBits(input)[3])[2];

    decimal factor = (decimal)Math.Pow(10,precision-1);

    return Math.Ceiling(input*factor)/factor;
}

static float RoundUp(float input)
{
    return (float)RoundUp((decimal)input);
}

输出:

DECIMAL
1.53
1.6
2
FLOAT
1.53
1.6
2

Running example

答案 1 :(得分:0)

var a = "1,53";

将此字符串拆分为两个,并计算小数位数:

var length = a.Split(',')[1].Length;

将原始字符串转换为双变量(将,替换为.以避免转换期间出现异常)

var b = Convert.ToDouble(a.Replace(',', '.'))

以指定的精度进行舍入:

var c = Math.Ceil(b, (length - 1));

并将返回的.替换为,的值:

return c.ToString().Replace('.', ',');

答案 2 :(得分:0)

为什么不使用10的幂进行简单的乘法,这有效地移动了小数点,您可以在其中调用Math.Ceiling来舍入该数字。除以相同的10的幂可以将小数点放回原来的位置。

使用decimal.ToString()来解决浮点精度问题,有关更多信息,请参见this blog post

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);
}

输出

  

1.53

     

1.6

     

2

     

-1.53​​

注意 Math.PowMath.Ceiling是对double的操作,因此从double投射到float

更新找出需要舍入到小数点后的位数,并使用小数点以“浮点数”精度“解决”问题。

更新2 使用decimal.GetBytes来获取数字的精度,而不是进行繁琐的文化不变性ToString().Split yada yada yada。

更新3 对负数从零舍入,并按位添加& 0xff以去除符号位。

答案 3 :(得分:0)

文化独立解决方案:

static double RoundUp(double val)
{
    double a = val;
    double decimals = a - ((int)a); //Gets only decimals
    double pow = Math.Pow(10, decimals.ToString().Length - 3); 
    a = a * pow;             //Multiply by a power of 10 | decimal shift
    a = Math.Ceiling(a);     //Round up
    a = a / pow;             //Shift back
    return a;
}

并这样称呼它:

var res = RoundUp(1.527); //1.53
res = RoundUp(1.53); //1.6
res = RoundUp(1.6); //2

或对于浮点数:

static float RoundUp(float val)
{
    float a = val;
    float t = a - ((int)a); //Gets only decimals
    float pow = (float)Math.Pow(10, t.ToString().Length - 3); 
    a = a * pow;             //Multiply by a power of 10 | decimal shift
    a = (float)Math.Ceiling(a);     //Round up
    a = a / pow;             //Shift back
    return a;
}


var res = RoundUp(1.527f); //1.53
res = RoundUp(1.53f); //1.6
res = RoundUp(1.6f); //2