通过计算零以科学计数法显示非常大或非常小的数字

Posted

技术标签:

【中文标题】通过计算零以科学计数法显示非常大或非常小的数字【英文标题】:Display very Large or Small Numbers in Scientific Notation by Counting the Zero's 【发布时间】:2019-03-30 02:19:52 【问题描述】:

当小数点前的数字也为零时,我需要一种方法来获取小数点后零的数量。因此,例如 0.00000000987654 将计算为 8,因为 0 后有 8 个零。将小数数据类型转换为字符串,然后我可以用科学记数法将其显示为 9.87654E9。

我需要这样做的原因是我可以多次迭代非常小的数字,从而产生对计算器来说太高的结果。

因此例如 0.123456789 乘以 0.1 并迭代 1000 次。 (0.123456789 * 0.1 * 0.1 * 0.1 * 0.1 ......) 使用具有完整 28 位精度并以科学记数法显示的十进制数据类型计算出 1.234567890000000000000000000E-1001

在使用 Factorials 时,我能够做到这一点。例如,1000 的阶乘是 1000 x 999 * 998 * 997 * 996 .... 一直到 0。这个数字对于计算器来说太高了,所以我使用迭代来实现科学计数法中 28 位精度的结果.

对于非常大的数字,我成功了。我通过在该期间之前获取位数来实现这一点:

    static int Get_Digits_Before_Period(decimal Large_Number)
    
        decimal d = decimal.Floor(Large_Number < 0 ? decimal.Negate(Large_Number) : Large_Number);
        // 0.xyz should return 0, therefore a special case
        if (d == 0m)
            return 0;
        int cnt = 1;
        while ((d = decimal.Floor(d / 10m)) != 0m)
            cnt++;
        return cnt;
    

我现在需要一种类似的方法,但需要一种方法来获取周期后零的数量。

【问题讨论】:

我不确定是否应该将其发布为答案,但我最终创建了一个可以以 28 位精度迭代非常大或小的数字的程序。 (例如 2.18961306137446848520669395 E-1376 )但是我不能确定精度是否准确。 【参考方案1】:

十进制的指数范围是0~-28,所以不能表示1.234567890000000000000000000E-1001这样的数字,所以我只解释有效范围内的数字。

要计算小数的零,您可以先获取小数的整数和指数部分

var number = 0.00000000987654m;
var bits = decimal.GetBits(number); //0~2 are integer part.
var exponent = (bits[3] & 0xff0000) >> 16;

然后将指数减少整数的有效数字以在句点后得到零计数。

var zeros = exponent;
for(int i = 0; i <= 2; i++)

      if(bits[i] != 0)
         zeros -= (int)Math.Log10(bits[i]) + 1;

if(zeros < 0)
    zeros = 0;

【讨论】:

以上是关于通过计算零以科学计数法显示非常大或非常小的数字的主要内容,如果未能解决你的问题,请参考以下文章

将非常小的双精度值转换为字符串(使用科学计数法)(Java)

将小数格式化为没有科学记数法的小数位数

Angularjs避免数字过滤器的科学记数法

与科学记数法 kableExtra table R markdown html 结合时,十进制后的数字不一致

如何在php中将非常小的、正常的、大的、科学的数字转换为字符串

如何让mssqlreal不用科学计数法显示