代码之家  ›  专栏  ›  技术社区  ›  D.R.

以升序遍历所有可表示的小数

  •  1
  • D.R.  · 技术社区  · 7 年前

    float (指数和尾数)一个接一个地循环,得到的浮点数从 0 float.MaxValue ,然后到 float.PositiveInfinity 然后进一步讨论 float.NaN

    这套不错的房子似乎暂时不能住了 decimal

    奖励:有没有快速的方法来计算可能的数字?

    附加信息:可以将1.0和1.00算作两个不同的数字。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Eric Postpischil    7 年前

    这个 decimal 格式有符号位 s ,96位有效位 ,和一个指数 e 从0到28(含28)。所代表的价值( s f e s f e .

    定义的规范表示( s , e s , f 10 n e + )对于最大整数 n f 10 <2 96 e ¤ 28如果 e 不是28,则规范有效位在天花板(2)中 /10), 2 96 1,包含在内。

    我们可以遍历非负 按升序排列的值:

        Set s = 0, e = 28.
        For f from 0 to 2^96 - 1, inclusive:
            Process (s, f, e) as a decimal value.
        For e from 27 down to 0, inclusive:
            For f from ceiling(2^96 / 10) to 2^96 - 1, inclusive:
                Process (s, f, e) as a decimal value.
    

    f 以比前一个循环结束的值更大的表示值开始。我们可以看到每个可表示的值都包含在内,因为任何规范表示的值( s , f , e f 哪里 e 有价值吗 e . 我们看不到任何值是重复的,因为每个可表示的值在其规范表示中只处理一次。

    U型 U型 e fL eL 成为 e 的正则表示 ,对于 fU eU

        (0) Set s to 0, f to fL, and e to eL.
        (1) If e ≤ eU and f > fU, stop.
        (2) Process (s, f, e) as a decimal number.
        (3) Set f to f+1.
        (4) If f is less than 2^96, go to (1).
        (5) Set e to e-1 and f to f/10.
        (6) Go to (1).
    

    负数的扩展是显而易见的。