最有效/正确的做法是在十进制结束时修剪无意义的零

时间:2012-01-17 14:01:34

标签: c# .net-4.0 decimal

这是SO的重复次数,但我想明确说明我的问题。

How is a decimal which would look like 2.0100 "rightly" presented to the user as 
another "decimal" 2.01?

我在SO上看到很多问题,输入是一个字符串“2.0100”,需要一个十进制2.01,并且问题在哪里需要十进制2.0100表示​​为字符串“2.01”。所有这些都可以通过基本的字符串来实现.Trim,decimal.Parse等。以下是一些方法:

  1. decimal.Parse(2.0100.ToString("G29"))

  2. 使用#literal

  3. 许多string.Format选项。

  4. 各种正则表达式选项

  5. 我自己用过的那个:

    if (2.0100 == 0)
        return 0;
    decimal p = decimal.Parse(2.0100.ToString().TrimEnd('0'));
    return p == 2.0100 ? p : 2.0100;
    
  6. 但我相信必须有一些正确的方法在.Net(至少4个)中处理数字操作而不是字符串操作。我要求的是一些不处理小数的字符串,因为我觉得这不是正确的方法。我正在努力学习新的东西。并且我希望自从我从数据库中提取数万个十进制值以来,至少可以看到.1秒的性能提升:)

    问题2:如果它存在于.Net中,这是获得小数的可呈现值的最有效的字符串方法吗?

    编辑:我不仅希望将小数呈现给用户。在那种情况下,我可以将它用作字符串。我确实想要它作为十进制。我将在以后处理这些十进制值。因此,通过ToString方法,我首先需要将其转换为字符串,然后再次将其解析为十进制。我正在寻找一些不涉及String类的东西。有些选项可将十进制.20100转换为十进制.201?

4 个答案:

答案 0 :(得分:2)

decimal值中出现的“额外零”是因为System.Decimal类型明确地存储了这些零。对于System.Decimal1.23400是来自1.234不同值,即使它们在数字上是相等的:

  

缩放因子还会保留十进制数中的任何尾随零。尾随零不影响算术或比较运算中的十进制数的值。但是,如果应用了适当的格式字符串,则ToString方法可以显示尾随零。

使用零是很重要的,因为许多十进制计算涉及significant digits,这是许多科学和高精度计算的必要条件。

在你的情况下,你不关心它们,但适当的答案不是“为我的特定应用程序改变十进制,以便它不存储那些零”。相反,它“以对我的用户有意义的方式呈现这个价值”。这就是 decimal.ToString() 的用途。

答案 1 :(得分:1)

为用户格式化给定格式的小数的最简单方法是使用decimal.ToString()的格式选项。

至于表示值,2.01等于2.0100。只要您处于decimal精度范围内,就应该如何将值存储在系统中。您应该只担心正确格式化用户的值。

答案 2 :(得分:1)

数字是数字,字符串是字符串。在英语中表示为字符串的“两个”的概念是2。表示为数字的“两个”的概念实际上不可能显示,因为当您观察数字时,您将其视为字符串。但为了争论,可能是22.00202.0或甚至10/5。这些都是“两个人”的代表。

您的数据库实际上并没有返回2.0100,您正在检查该值的是将其转换为字符串并以此方式表示它。一个数字在其末尾是否为零只是字符串格式的偏好,总是。

此外,永远不要在小数点上调用Decimal.parse(),这没有意义。如果要将十进制文字转换为字符串,只需调用(2.0100).ToString().TrimEnd('0')

答案 3 :(得分:1)

如上所述,内部存储2.0100的小数可能与存储2.01的小数不同,ToString()的默认行为可能会受到影响。

我建议你永远不要使用它。

首先,decimal.Parse("2.0100") == decimal.Parse("2.01")返回true。虽然他们的内部代表不同,但这是IMO的不幸。当我使用值为2.01的decimal时,我想要思考:

2.01

struct decimal   {     private int flags;     private int hi;     私人的;     私人中期;     / 使这个实际有用的方法 /   }

虽然可能存在在上述结构中存储2.01的不同方法,但2.01仍为2.01。

如果您关心它被显示为2.01而不是2.02.0100,那么您关心字符串表示。您关心的是如何将小数表示为字符串,这就是您应该在该阶段如何考虑它。考虑相关规则(显示的最小和最大有效数字,以及是否包括或排除尾随零),然后编写适当的ToString调用代码。

并且接近使用字符串的位置。

当您关心2.01时,请将其作为小数处理,并考虑2.012.0100之间的差异重要的任何代码,并修复它。

在您使用字符串的位置和使用小数位的位置之间清楚地划分代码。