如何在不带尾随零的情况下设置小数格式
本文关键字:情况下 设置 小数 格式 | 更新日期: 2023-09-27 18:21:18
我刚刚了解到,小数以某种方式记住了存储一个数字需要多少尾随零。换句话说:它记住分数的大小。
例如:
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
删除新字符串末尾的零对我来说不是一个真正的选择,因为这样我必须找出字符串是否包含分数,如果是,还必须删除可选的"."或",具体取决于文化等。
有几种方法可以做到这一点,但由于您无论如何都要转换为 String 对象,我想您可以尝试这样的事情:
myDecimalVariable.ToString("G29");
或者,使用上面的代码,假设123.00M
是你的小数:
123.00M.ToString("G29");
以下是该简洁示例如何工作的解释:
带有数字的 G 格式意味着格式化许多重要的 数字。因为 29 是小数点可以得出的最有效数字 有,这将有效地截断尾随零,而无需 舍入。
只需应用格式说明符零,并将删除尾随零:
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');
下面的 方法((处理以下边缘情况:
- 输入: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");
}