为了账号安全,请及时绑定邮箱和手机立即绑定

C#浮点数总是向上

C#浮点数总是向上

C#
湖上湖 2021-11-21 15:15:03
我想在 C# 中实现一个函数,它需要一个浮点数,它会输出四舍五入的一个(总是向上):1,527 -> 1,531,53 -> 1,61,6 -> 2最简单的方法是什么?编辑:稍微澄清一下 - 我希望它设置适当的 2D 图形轴的最大值,所以如果最大值是 1,527,我想做这个函数的几次迭代,直到舍入值高于例如 10%,所以对于 1,527,最大值可能是 1,6,因此 1,527 适合几乎同时完全使用的图
查看完整描述

4 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

使用这个问题的标记答案:


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


查看完整回答
反对 回复 2021-11-21
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

为什么不通过简单的 10 次幂乘法来实现,这可以有效地移动小数点,您可以在其中调用 Math.Ceiling 将数字向上取整。除以 10 的相同幂以将小数点放回原来的位置。


使用decimal.ToString()为“避开”的浮点精度的问题,看到这个博客帖子获取更多信息


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.Pow和Math.Ceiling是对 的操作double,因此强制转换为doublefromfloat


更新计算出它需要舍入到多少小数位并使用小数来“解决”浮点精度问题。


更新 2用于decimal.GetBytes获得数字的精度,而不是执行相当繁琐的文化不变ToString().Splityada yada yada。


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


查看完整回答
反对 回复 2021-11-21
?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

独立于文化的解决方案:


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


查看完整回答
反对 回复 2021-11-21
?
不负相思意

TA贡献1777条经验 获得超10个赞

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('.', ',');


查看完整回答
反对 回复 2021-11-21
  • 4 回答
  • 0 关注
  • 194 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信