如何格式化小数并去掉末尾的零

13

我刚刚学到,十进制数在存储数字时会记住需要多少个尾随零。换句话说:它会记住小数的大小。

例如:

123M.ToString() ==> resuls in: 123
123.00M.ToString() ==> resuls in: 123.00
123.450M.ToString() ==> resuls in: 123.450

我正在寻找一种格式化字符串或其他技巧,以去除那些“不必要”的尾随零,但保留有效数字。所以:

123M.ToString() ==> resuls in: 123
123.00M.ToString() ==> resuls in: 123
123.450M.ToString() ==> resuls in: 123.45

对我来说,删除新字符串末尾的零不是一个真正的选择,因为那么我就必须找出字符串是否包含分数,如果是,则还必须根据文化习惯删除可选的'.'或','等字符。


我认为这个话题的最佳答案是这个 - keyboardP
可能是去除尾随零的重复问题,该问题较旧且具有更好的答案和评论。 - Sam
3个回答

16

有几种方法可以实现,但既然您无论如何都要将其转换为String对象,我认为您可以尝试像这样做:

myDecimalVariable.ToString("G29");

或者,使用您上面的代码,假设 123.00M 是您的decimal:

123.00M.ToString("G29");

下面是这个简洁示例的解释:

G格式与数字一起使用表示格式化那么多个有效数字。因为29是一个Decimal可以拥有的最重要的数字,所以这将有效地截断尾随的零而不进行四舍五入。


5
请参考此评论,有关于G29可能无法按预期工作的一些情况。 - keyboardP
对,但他的例子没有包括这些情况,所以我认为这是最简单的方法来达到他想要的。但现在知道这点也是不错的。 - Michael Hawkins
1
你的答案并没有错,但我认为值得一提,以防其他人遇到这个问题。 - keyboardP
2
我完全同意。谢谢。 - Michael Hawkins
4
“G0” 的工作方式与此类似。请参阅 标准数值格式字符串 - 通用 ("G") 格式说明符 - Jeppe Stig Nielsen
显示剩余2条评论

0

只需应用格式说明符零,即可删除尾随的零:

string test = (1.23M * 100M).ToString("0");
//prints 123.
string test2 = 123.450M.ToString(".00");
//prints 123.45.
string test3 = 123.450M.ToString().Trim('0');

请注意,Trim('0') 会将格式为 0.5m 的内容格式化为 .5 而非 0.5 - Sam

0

以下方法 () 处理以下边缘情况:

  • 输入:123.00M,期望值为 "123.00"
    • ❌ G29: 123
    • ✅ : 123.00
  • 输入:-0.00000000001M,期望值为 "-0.00000000001"
    • ❌ G29: -1E-11
    • ✅ : -0.00000000001
private static string SlowButStrong(decimal v)
{
  if( v % 1 == 0) return v.ToString(); // If no decimal digits, let's leave it alone
  var withNoZeroes = v.ToString().TrimEnd('0');
  return withNoZeroes.EndsWith('.') ? withNoZeroes + "00" : withNoZeroes;
}

测试输出

Input 123M, expecting 123
✅ G29: 123
✅ : 123
✅ ⛵: 123

Input 123.00M, expecting 123.00
❌ G29: 123
✅ : 123.00
❌ ⛵: 123

Input 123.45M, expecting 123.45
✅ G29: 123.45
✅ : 123.45
✅ ⛵: 123.45

Input 123.450M, expecting 123.45
✅ G29: 123.45
✅ : 123.45
✅ ⛵: 123.45

Input 5.00000001M, expecting 5.00000001
✅ G29: 5.00000001
✅ : 5.00000001
✅ ⛵: 5.00000001

Input -0.00000000001M, expecting -0.00000000001
❌ G29: -1E-11
✅ : -0.00000000001
✅ ⛵: -0.00000000001

Input 10000000000000000000000M, expecting 10000000000000000000000
✅ G29: 10000000000000000000000
✅ : 10000000000000000000000
✅ ⛵: 10000000000000000000000

任意测试用例

public static void Main(string[] args)
{
    Test("123M", 123M, "123");
    Test("123.00M", 123.00M, "123.00");
    Test("123.45M", 123.45M, "123.45");
    Test("123.450M", 123.450M, "123.45");
    Test("5.00000001M", 5.00000001M, "5.00000001");
    Test("-0.00000000001M", -0.00000000001M, "-0.00000000001");
    Test("10000000000000000000000M", 10000000000000000000000M, "10000000000000000000000");
}

private static void Test(string vs, decimal v, string expected)
{
    Console.OutputEncoding = System.Text.Encoding.UTF8;

    Console.WriteLine($"Input {vs}, expecting {expected}");
    Print("G29", v.ToString("G29"), expected);
    Print("", SlowButStrong(v), expected);
    Print("⛵", LessSlowButStrong(v), expected);
    Console.WriteLine();
}

private static void Print(string prefix, string formatted, string original)
{
    var mark = formatted == original ? "✅" : "❌"; 
    Console.WriteLine($"{mark} {prefix:10}: {formatted}");
}

private static string SlowButStrong(decimal v)
{
    if( v % 1 == 0) return v.ToString(); // If no decimal digits, let's leave it alone
    var withNoZeroes = v.ToString().TrimEnd('0');
    return withNoZeroes.EndsWith('.') ? withNoZeroes + "00" : withNoZeroes;
}

private static string LessSlowButStrong(decimal v)
{
    return v.ToString((v < 1) ? "" : "G29");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接