增加浮点数的第n位数

时间:2014-01-29 17:20:35

标签: c# floating-point

我正在创建一个控件,我需要递增或递减浮点数的第n位。例如,如果我想增加:

12.3456    I want to increment the thousand (5) to 6
     ^

然后我会写12.3466

当数字不大(少数有效数字)时,这很简单。以223456.109f为例,如果我想增加第一个2,我想以323456.109f = 323456.1结束(c#轮次323456.109到323456.1,以便它可以适合32位)。我现在正在做的是添加100000.问题是如果我向223456.109f添加10000,那么我将323456.125f323456.1f不同。

我该如何解决这个问题。我是否必须将其转换为字符串然后使用字符串进行数学运算?

修改

感谢您的回答,这是我的方法:

    /// <summary>
    /// Increments the nth digit of a float number
    /// </summary>
    /// <param name="floatToIncrement">The number we are incrementing such as 12.34E+20f </param>
    /// <param name="positionToIncrement"> See example inside method. </param>        
    /// <param name="incrementOrDecrement">If true it will increment if false it will decrement</param>
    /// <returns></returns>
    static float IncrementFloat(float floatToIncrement, short positionToIncrement, bool incrementOrDecrement=true)
    {
        /* Example:
           10.5678

           1 = positionToIncrement ->  2
           0 = positionToIncrement ->  1
           5 = positionToIncrement -> -1
           6 = positionToIncrement -> -2
           etc
         */

        if (positionToIncrement == 0)
            return floatToIncrement;

        var floatToIncrementAsString = floatToIncrement.ToString("R");

        // a float number may be 1.20E+20 let's match it so that we can remove the E+20
        var match = Regex.Match(floatToIncrementAsString, @"(\d[^E]+)(.*)"); 

        var decimalNum = decimal.Parse(match.Groups[1].Value);

        // if position is greater than 0 we increment the nth digit to the left of the '.'
        if(positionToIncrement>0)
        {
            var numToAdd = int.Parse("1".PadRight(positionToIncrement, '0'));
            if (incrementOrDecrement)
                decimalNum += numToAdd;
            else
                decimalNum -= numToAdd;
        }
        else // else we do the same but to the right of the '.'
        {
            var x = Math.Abs(positionToIncrement);
            var y = "1".PadRight(x+1, '0');
            var numToAdd = int.Parse(y);

            if (incrementOrDecrement)
                decimalNum += 1 / ((decimal)(numToAdd));
            else
                decimalNum -= 1 / ((decimal)(numToAdd));
        }

        var result = decimalNum + match.Groups[2].Value;

        return float.Parse(result);            
    }

2 个答案:

答案 0 :(得分:1)

您可以使用decimal数据类型,它有28-29位有效数字,因此它可以解决您的问题。

近似范围

( - 7.9 x 10 28 至7.9 x 10 28 )/(10 0至28

<强>精密

28-29有效数字

Float

比较

精确度

7位有效数字。

如果必须避免舍入错误,请始终使用decimal

decimal具有比float更重要的数字,因此它可以更精确 - 它也占用更多的内存。除了某些数学或物理相关的算法,double或float应该没问题。

答案 1 :(得分:1)

如果您需要精确值,则不应使用floatdouble。请改用decimal

  

Decimal值类型适用于需要大量有效积分和小数位以及无四舍五入错误的财务计算。

     来自Decimal Structure