使用度量衡前缀格式化数字?

14
可能重复: C#中的工程表示法? 使用公制前缀是否比科学计数法更好,这可能是有争议的,但我认为对于物理单位它有其用例。
我查看了一下,似乎.NET没有任何内置的类似功能,或者我对此有误解?实现它的任何方法都可以。
澄清一下:目标是将任何给定的数字显示为浮点或整数字符串,其值在1和999之间,并带有相应的公制前缀。
例如,
1000 -> 1k 0.05 -> 50m
进行四舍五入:
1,436,963 -> 1.44M

1
这里并不是很清楚你在问什么。请提供输入和期望输出的样例。 - Daniel Hilgarth
你的意思是将 12345000 转换为 12.34M 而不是 1.234e007 吗?据我所知,目前没有内置支持此功能的方法。 - verdesmarald
@DanielHilgarth:添加了一些澄清。 - H.B.
@veredesmarald:是的,我也是这么认为的。 - H.B.
@H.B.:感谢您。不幸的是,我不知道有任何库可以做到这一点。 - Daniel Hilgarth
@DanielHilgarth:嗯,我认为使用一个表示数量级的字典实现应该很容易,但是我希望有.NET内置的函数可以实现它,但我认为没有这样的函数。也许我会自己写一个…… - H.B.
3个回答

14

试一下这个。虽然我没有测试过,但应该基本正确。

public string ToSI(double d, string format = null)
{
    char[] incPrefixes = new[] { 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
    char[] decPrefixes = new[] { 'm', '\u03bc', 'n', 'p', 'f', 'a', 'z', 'y' };

    int degree = (int)Math.Floor(Math.Log10(Math.Abs(d)) / 3);
    double scaled = d * Math.Pow(1000, -degree);

    char? prefix = null;
    switch (Math.Sign(degree))
    {
        case 1:  prefix = incPrefixes[degree - 1]; break;
        case -1: prefix = decPrefixes[-degree - 1]; break;
    }

    return scaled.ToString(format) + prefix;
}

2
可能需要一些针对非常小或非常大的数字的错误处理,但总体上它是有效的。 - H.B.
2
在函数入口处检查d是否为0是有用的,因为否则degree会取得“-无穷大”值。 - LucaG
1
我在这里强调一下,如果 d 为零,程序将会崩溃(正如 @LucaG 已经暗示的那样)。对 -Infinity 取反或者在这种情况下取反 Int32.MinValue 将导致溢出异常。 - greyhairredbear
@LPeteR90 可以提交编辑。我自己已经多年没有碰过 C# 了。 - Thom Smith

1
为每种数字类型创建一个扩展方法。您可以调用ToStringMetric()来进行自定义格式化。
public static class Int32Extensions
{
        public static string ToStringMetric(this Int32 x) { return (x / 1000).ToString() + " K"; }
}

1
根据这些SO 文章和我的研究,目前没有本地化的方法来格式化公制单位的数字。你需要编写自己的方法来解析单位并附加相关的公制度量单位,例如MSDN上这个界面教程的扩展示例。你也可以尝试找到一个公制单位编程库来使用进行开发。

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