使大,小号码人类可读 [英] Make big and small numbers human-readable

查看:185
本文介绍了使大,小号码人类可读的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想打印我在C#中非常小的数字在人类友好的方式,如:



30μ 3E-5 456.789n 0.000000456789



我知道的 Humanize_number ()从BSD的C函数,但只有位整数,而不是花车和双打兼容。


$:有在C#支持这些等效



此外,应该显示数字,例如当保持一定的精度b $ b

0.003596 应显示为3.596μ,而不是3.6μ(或更糟的是,)。



下面的可能的答案:格式化大与.NET 号码,但改编为负log10的是逗号后截断号码1位数。



<$ P $:我想如何呈现的东西是远远没有完成,我认为



例子p> 3000 3K
3300 3.3K
3333 3.333K
30000 30,000
300000 30万
3000000 3M
3000003 3.000003M / /或3M如果我指定4个数字精确
0.253253米
0.025325.3米
0.002532.53米
-0.253003 -253.003m

我不能制定我的问题找到SO相关的答案,因此,如果这个问题已经已经回答了,火了!


解决方案

试试这个:

 静态类扩展
{
静态字符串[]前缀= {F,一个,p,N,μ,M,的String.Empty,K,M ,G,T,P,E};

公共静态字符串尼斯(这双X,诠释有效位数)
{
//检查特殊数字和非数字
如果(double.IsInfinity(X )|| double.IsNaN(X)||点¯x== 0 ||有效位数< = 0)
{
返回x.ToString();
}
//提取物的迹象,所以我们处理正数只有
INT标志= Math.Sign(X);
X = Math.Abs​​(X);
//获取科学的指数,10 ^ 3,10 ^ 6,...
INT SCI = X == 0? 0:(INT)Math.Floor(将Math.log(X,10)/ 3)* 3;
//规模数量指数发现
X = X * Math.Pow(10,-sci);
//找到小数点
INT DG = X == 0左侧的位数? 0:(INT)Math.Floor(将Math.log(X,10))+ 1;
//调整小数显示
INT小数= Math.Min(有效位数-DG,15);
//为小数
串FMT =新的字符串('0',小数)格式;
如果(SCI == 0)
{
//没有指数
返回的String.Format({0} {1:0+ FMT +},
符号℃, - :的String.Empty,
Math.Round(X,小数));?
}
//找到前缀索引。 SCI的每3是一个新的索引
INT指数= SCI / 3 + 6;
如果(索引> = 0&放大器;&安培;指数< prefixes.Length)
{
//前缀
返回的String.Format({0} {1:0。 + FMT +} {2},
迹象℃的? - :的String.Empty,
Math.Round(X,小数),
前缀[指数]);
}
// 10 ^ EXP格式
返回的String.Format({0} {1:0+ FMT +}×10 ^ {2},
符号℃, - :的String.Empty,
Math.Round(X,小数),
SCI);?
}

//测试代码
静态无效的主要(字串[] args)
{
双X = Math.PI / 10e20;

{
Console.WriteLine(的String.Format({\t 0,20} = {1},X,x.Nice(4)));
X * = 10;
},而(X< = Math.PI * 10e20);
}
}

有四个显著的数字测试输出:



  3.14159265358979E-19 = 314.2×10 ^ -2 
1.5707963267949E-18 = 1.571f
7.85398163397448E-18 = 7.854f
3.92699081698724E-17 = 39.27f
1.96349540849362E-16 = 196.3f
9.8174770424681E-16 = 981.7f
4.90873852123405E-15 = 4.909a
2.45436926061703E-14 = 24.54a
1.22718463030851E-13 = 122.7a
6.13592315154256E-13 = 613.6a
3.06796157577128E-12 = 3.068p
1.53398078788564E-11 = 15.34p
7.6699039394282E-11 = 76.70p
3.8349519697141E-10 = 383.5p
1.91747598485705E-09 = 1.917n
9.58737992428526E-09 = 9.587n
4.79368996214263E-08 = 47.94n
2.39684498107131E-07 = 239.7n
1.19842249053566E-06 =1.198μ
5.99211245267829E-06 =5.992μ
2.99605622633914E-05 = 29.96 μ
0.000149802811316957 =149.8μ
0.000749014056584786 =749.0μ
0.00374507028292393 =3.745米
0.0187253514146196 =18.73米
0.0936267570730982 =93.63米
0.468133785365491 =468.1米
2.34066892682745 = 2.341
11.7033446341373 = 11.70
58.5167231706864 = 58.52
292.583615853432 = 292.6
1462.91807926716 = 1.463k
7314.5903963358 = 7.315k
36572.951981679 = 36.57 ķ
182864.759908395 = 182.9k
914323.799541975 = 914.3k
4571618.99770987 = 4.572M
22858094.9885494 = 22.86M
114290474.942747 = 114.3M
571452374.713734 = $ 571.5M b $ b 2857261873.56867 = 2.857G
14286309367.8434 = 14.29G
71431546839.2168 = 71.43G
357157734196.084 = 357.2G
1785788670980.42 = 1.786T
8928943354902.1 = 8.929T
44644​​716774510.5 = 44.64T
223223583872552 = 223.2T
1.11611791936276E + 15 = 1.116P
5.58058959681381E + 15 = 5.581P
2.79029479840691E + 16 = 27.90P
1.39514739920345E + 17 = 139.5P
6.97573699601726E + 17 = 697.6P
3.48786849800863E + 18 = 3.488E
1.74393424900432E + 19 = 17.44E
8.71967124502​​158E + 19 = 87.20 Ë
4.35983562251079E + 20 = 436.0E
2.1799178112554E + 21 = 2.180×10 ^ 21


I would like to print my very small numbers in C# in a human friendly way, such as:

30µ for 3E-5 or 456.789n for 0.000000456789.

I know of the Humanize_number() function from BSD in C, but only compatible with bit ints, not floats and doubles. Is there the equivalent in C# that supports those?

Also, it should keep a certain amount of precision when displaying numbers, like:

0.003596 should be displayed as 3.596µ, not 3.6µ (or worse, ).

The possible answer here: Formatting Large Numbers with .NET but adapted for negative log10 is truncating the numbers to 1 digit after the comma. That's far from complete in my opinion.

Examples of how I'd like to present things:

3000        3K
3300        3.3K
3333        3.333K
30000       30k
300000      300k
3000000     3M
3000003     3.000003M // or 3M if I specify "4 digits precision"
0.253       253m
0.0253      25.3m
0.00253     2.53m
-0.253003   -253.003m

I couldn't formulate my question to find relevant answers in SO, so if the question has been already answered, fire away!

解决方案

Try this:

static class Extensions
{
    static string[] prefixes= { "f", "a", "p", "n", "μ", "m", string.Empty, "k", "M", "G", "T", "P", "E" };

    public static string Nice(this double x, int significant_digits)
    {
        //Check for special numbers and non-numbers
        if(double.IsInfinity(x)||double.IsNaN(x)||x==0||significant_digits<=0)
        {
            return x.ToString();
        }
        // extract sign so we deal with positive numbers only
        int sign=Math.Sign(x);
        x=Math.Abs(x);
        // get scientific exponent, 10^3, 10^6, ...
        int sci= x==0? 0 : (int)Math.Floor(Math.Log(x, 10)/3)*3;
        // scale number to exponent found
        x=x*Math.Pow(10, -sci);
        // find number of digits to the left of the decimal
        int dg= x==0? 0 : (int)Math.Floor(Math.Log(x, 10))+1;
        // adjust decimals to display
        int decimals=Math.Min(significant_digits-dg, 15);
        // format for the decimals
        string fmt=new string('0', decimals);
        if(sci==0)
        {
            //no exponent
            return string.Format("{0}{1:0."+fmt+"}",
                sign<0?"-":string.Empty,
                Math.Round(x, decimals));
        }
        // find index for prefix. every 3 of sci is a new index
        int index=sci/3+6;
        if(index>=0&&index<prefixes.Length)
        {
            // with prefix
            return string.Format("{0}{1:0."+fmt+"}{2}",
                sign<0?"-":string.Empty,
                Math.Round(x, decimals),
                prefixes[index]);
        }
        // with 10^exp format
        return string.Format("{0}{1:0."+fmt+"}·10^{2}",
            sign<0?"-":string.Empty,
            Math.Round(x, decimals),
            sci);
    }

    // test code
    static void Main(string[] args)
    {
        double x=Math.PI/10e20;
        do
        {
            Console.WriteLine(string.Format( "\t{0,20} = {1}", x, x.Nice(4)));
            x*=10;
        } while(x<=Math.PI*10e20);
    }
}

Test output with four significant digits:

    3.14159265358979E-19 = 314.2·10^-2
     1.5707963267949E-18 = 1.571f
    7.85398163397448E-18 = 7.854f
    3.92699081698724E-17 = 39.27f
    1.96349540849362E-16 = 196.3f
     9.8174770424681E-16 = 981.7f
    4.90873852123405E-15 = 4.909a
    2.45436926061703E-14 = 24.54a
    1.22718463030851E-13 = 122.7a
    6.13592315154256E-13 = 613.6a
    3.06796157577128E-12 = 3.068p
    1.53398078788564E-11 = 15.34p
     7.6699039394282E-11 = 76.70p
     3.8349519697141E-10 = 383.5p
    1.91747598485705E-09 = 1.917n
    9.58737992428526E-09 = 9.587n
    4.79368996214263E-08 = 47.94n
    2.39684498107131E-07 = 239.7n
    1.19842249053566E-06 = 1.198µ
    5.99211245267829E-06 = 5.992µ
    2.99605622633914E-05 = 29.96µ
    0.000149802811316957 = 149.8µ
    0.000749014056584786 = 749.0µ
     0.00374507028292393 = 3.745m
      0.0187253514146196 = 18.73m
      0.0936267570730982 = 93.63m
       0.468133785365491 = 468.1m
        2.34066892682745 = 2.341
        11.7033446341373 = 11.70
        58.5167231706864 = 58.52
        292.583615853432 = 292.6
        1462.91807926716 = 1.463k
         7314.5903963358 = 7.315k
         36572.951981679 = 36.57k
        182864.759908395 = 182.9k
        914323.799541975 = 914.3k
        4571618.99770987 = 4.572M
        22858094.9885494 = 22.86M
        114290474.942747 = 114.3M
        571452374.713734 = 571.5M
        2857261873.56867 = 2.857G
        14286309367.8434 = 14.29G
        71431546839.2168 = 71.43G
        357157734196.084 = 357.2G
        1785788670980.42 = 1.786T
         8928943354902.1 = 8.929T
        44644716774510.5 = 44.64T
         223223583872552 = 223.2T
    1.11611791936276E+15 = 1.116P
    5.58058959681381E+15 = 5.581P
    2.79029479840691E+16 = 27.90P
    1.39514739920345E+17 = 139.5P
    6.97573699601726E+17 = 697.6P
    3.48786849800863E+18 = 3.488E
    1.74393424900432E+19 = 17.44E
    8.71967124502158E+19 = 87.20E
    4.35983562251079E+20 = 436.0E
     2.1799178112554E+21 = 2.180·10^21 

这篇关于使大,小号码人类可读的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆