【问题标题】:C# equivalent of BigDecimal.stripTrailingZeros()C# 等效于 BigDecimal.stripTrailingZeros()
【发布时间】:2011-02-21 14:38:14
【问题描述】:

在 Java 中,您可以使用 BigDecimal.stripTrailingZeros() 删除末尾的任何多余零。

我在这里阅读了一些关于如何在 C# 中从小数中去除尾随零的问题,但它们似乎都没有提供正确的解决方案。

This question 例如,执行 ToString("G") 的答案并不总是有效。

理想情况下,我想要一个执行小数 -> 小数的函数,新的小数具有尽可能小的比例,而不会丢失任何信息或删除任何尾随零。

有什么方法可以轻松做到这一点?还是会涉及摆弄decimal.GetBits()

编辑:还应该补充一点,我有 i18n 担心因此对结果进行字符串操作并不理想,因为小数分隔符存在差异。

【问题讨论】:

标签: c# decimal strip


【解决方案1】:

Decimal.Parse(d.ToString("0.###########################"))怎么样?

【讨论】:

  • 它不起作用.. decimal.Parse(1000.001M.ToString("0.#")) 给了1000 我们在小数点后丢失了001
  • 再次失败 1000.000000000000000000000000000100M 哈哈 将其扩展到可用的最大位数:D
  • 好的,你的答案有效.. 我多余的数字实际上被截断了
  • +1 我用我的示例测试了您的代码,它可以工作..+1 在这里获得最简单的答案..
【解决方案2】:

这是我想出的(疯狂的代码,但运行顺利)

private decimal Normalize(decimal d)
{
    string[] tmp = d.ToString().Split('.');
    string val = tmp[0];    
    string fraction = null;
    decimal result;
    if(tmp.Length > 1) fraction = tmp[1];
    if(fraction != null && Getleast(fraction) > 0) 
    {
        decimal.TryParse(val.ToString() + "." + fraction.TrimEnd('0').ToString(),out result);
    }
    else
    {
        return decimal.Parse(val);
    }
    return result;
}

private decimal Getleast(string str)
{
    decimal res;
    decimal.TryParse(str.TrimEnd('0'),out res);// It returns 0 even if we pass null or empty string
    return res;
}

这里是示例输入:

Console.WriteLine(Normalize(0.00M));
Console.WriteLine(Normalize(0.10M));
Console.WriteLine(Normalize(0001.00M));
Console.WriteLine(Normalize(1000.01M));
Console.WriteLine(Normalize(1.00001230M));
Console.WriteLine(Normalize(0031.200M));        
Console.WriteLine(Normalize(0.0004000M));
Console.WriteLine(Normalize(123));

以及各自的输出:

0
0.1
1
1000.01
1.0000123
31.2
0.0004
123

【讨论】:

  • 不是那么简单,您需要先检查是否存在小数点。否则你会得到像 ideone.com/DXokE 这样荒谬的结果
  • 是的,我正在使用我的 LINQPAD 来获得与字符串一起工作的东西......直到那时,也许标记答案是好的
【解决方案3】:

不是最优雅的解决方案,但它应该可以满足您的所有需求。

 private decimal RemoveTrailingZeros(decimal Dec)
    {
        string decString = Dec.ToString();

        if (decString.Contains("."))
        {
            string[] decHalves = decString.Split('.');

            int placeholder = 0, LoopIndex = 0;

            foreach (char chr in decHalves[1])
            {
                LoopIndex++;
                if (chr != '0')
                    placeholder = LoopIndex;
            }

            if (placeholder < decHalves[1].Length)
                decHalves[1] = decHalves[1].Remove(placeholder);

            Dec = decimal.Parse(decHalves[0] + "." + decHalves[1]);
        }

        return Dec;
    }

已修复版本,感谢 Shekhar_Pro!

【讨论】:

  • RemoveTrailingZeros(1000.01M) 在行 decHalves[1] = decHalves[1].Remove(placeholder);``ArgumentOutOfRangeException 异常
  • 十进制我们没有任何 i18n 问题..当我们将其转换为字符串时..您始终可以针对此特定处理进行文化中性字符串转换...
猜你喜欢
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 2011-06-03
相关资源
最近更新 更多