【问题标题】:Decimal - truncate trailing zeros十进制 - 截断尾随零
【发布时间】:2011-02-12 11:11:37
【问题描述】:

我注意到 .NET 在小数和尾随零方面有一些古怪/不直观的行为。

0m == 0.000m //true
0.1m == 0.1000m //true

但是

(0m).ToString() == (0.000m).ToString() //false
(0.1m).ToString() == (0.1000m).ToString() //false

我知道遵守 ECMA CLI 标准的必要性。 但是我想知道是否有内置方法可以在不通过字符串表示的情况下截断十进制值的尾随零(.ToString("G29") 和解析返回技巧会起作用,但既不是快速也不是优雅的解决方案) ?

有什么想法吗? 非常感谢。

【问题讨论】:

  • 嗯...我在想一些涉及decimal.GetBits 和 96 位算术的东西,但并不简单。
  • 请参阅stackoverflow.com/questions/1584314 了解相关问题。那里的答案之一给出了除以 1.000....0000m 以有效去除尾随零的技巧(大概是因为商 x/y 的“理想”指数是 x 和 y 的指数之差)。令人惊讶的是,没有 normalize 方法。

标签: c# decimal


【解决方案1】:

我认为你需要的是这个(更多细节在我的回答here):

public static decimal Normalize(decimal value)
{
    return value/1.000000000000000000000000000000000m;
}

【讨论】:

【解决方案2】:

使用格式字符串指定 ToString() 的输出:

(0.1m).ToString("0.#") -> "0.1"
(0.10000m).ToString("0.#") -> "0.1"

在格式中使用“0”指定数字或无意义的0,使用“#”指定有效数字或抑制无意义的0。

编辑:我在这里假设您担心数字的视觉(字符串)表示 - 如果不是,我将删除我的答案。

【讨论】:

  • 我不太关心视觉表现。问题是,当我将这些值传递给 JScript 引擎时,由于某种原因,它会被 1.0000m 类型值弄乱。尽管如此,还是谢谢您的回答。附言0.10000m.ToString("G29") 适用于任意数量的有效数字。
  • 这也会对值进行四舍五入,例如应用 0.# 的 123.4567 变为 123.5
【解决方案3】:

我不太喜欢它,但它有效(至少对于某些值范围)...

    static decimal Normalize(decimal value)
    {
        long div = 1;
        while(value - decimal.Truncate(value) != 0)
        {
            div *= 10;
            value *= 10;
        }
        if(div != 1) {
            value = (decimal)(long)value / div;
        }
        return value;
    }

【讨论】:

  • 它适用于大多数情况。不幸的是,它不适用于 0.00000m 类型的值。它需要另一个“if”来检查十进制零,这会使它更加混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 2016-11-24
  • 2011-04-28
  • 2015-01-31
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多