生成n个不是∞或NaN的不同浮点数(在Go中)

Ted*_*Ted 3 floating-point nan type-conversion go infinity

我想要一个函数getNthFloat(uint32 n) float32,对于每个n,m <2³²-4,其中n≠m,getNthFloat(n)getNthFloat(m)返回不同的浮点数,即实数(NaN和±∞).选择2³²-4是因为如果我正确理解IEEE 754,则存在两个NaN的二进制表示,一个用于∞,一个用于-∞.

我想我应该将我的uint32转换为位并将位转换为float32,但我无法弄清楚如何有效地避免这四个值.

Art*_*Art 7

你不能在float32中获得2 ^ 32-4个有效浮点数.IEEE 754二进制32号具有两个无穷大(负和正)和2 ^ 24-2个可能的NaN值.

32位浮点数具有以下位:

31   30...23  22...0
sign exponent mantissa
Run Code Online (Sandbox Code Playgroud)

值为0xff的所有指数都是无穷大(当尾数为0时)或NaN(当尾数不为0时).所以你不能生成那些指数.

然后,这只是一个简单的问题或将允许的整数映射到这种格式,然后用于math.Float32frombits生成float32.你如何做到这一点是你的选择.我可能很懒,只需使用符号的最低位,然后拒绝高于2 ^ 32 - 2 ^ 24 - 1的所有数字,然后移位这些位.

所以像这样(未经测试):

func foo(n uint32) float32 {
    if n >= 0xff000000 {
        panic("xxx")
    }
    return math.Float32frombits((n & 1) << 31 | (n >> 1))
}
Run Code Online (Sandbox Code Playgroud)

NB我可能还会避免非正规数,即指数为0且非零尾数的数字.它们可能很慢,可能无法正确处理.例如,它们都可以映射到零,在go规范中没有任何内容可以解释如何处理非规范数字,所以我要小心.