函数从整数到[0,1]浮点间隔

时间:2011-01-01 20:20:21

标签: c++ c math

给定一个整数,我想在区间[0,1]中产生一个唯一的浮点数。 (此号码将用作id)。 我发现我遇到的所有函数的问题是它们在用完整数值之前遇到重复。 例如,如果是f(a:int):float = 0.a,那么f(16000) = 0.16f(16001) = 0.16001。但由于它是浮点数,0.160.16001可能表示相同。 换句话说,我需要一个函数,不仅可以生成唯一的数字,还可以生成唯一的数字(至少是C ++整数域)。

我知道答案取决于特定环境中整数和浮点的大小,但是如果你能给出一个特定大小的例子,它仍然会有所帮助。

6 个答案:

答案 0 :(得分:8)

正如其他人指出的那样,您可以简单地将int投射到相同大小的float以获得唯一的浮点数(对NaN和{{1进行一些后置过滤}和-0)。但是,这不符合您在[0,1]中的要求。实际上,您可以使用该关系来表示[0,1]中没有足够的浮点数来表示整数集。如果你使用Inf那么尾数对于32位int来说足够大,而像double这样的表达式就足够了(如果你需要,显然允许无符号)。

答案 1 :(得分:5)

如果23位足够,你可以像int n那样构建一个浮点数:

float f;
*((__int32*)&f) = (0x7E<<23) | (n & 0x7FFFFF); // exponent=0x7E-0x7F=-1, fraction=n

它将根据IEEE浮点标准将整数[0,2 ^ 23-1]映射到浮点数[0.5,1.0]。

如果23位不够,您可以在自己引用的链接上找到解决方案。顺便提一下,还有一些其他重要的注意事项,一定要了解所有限制。

答案 2 :(得分:1)

使用1/(float)n这是一个很好的分配函数,如果n为零,则设置为0。

答案 3 :(得分:1)

这就像散列函数和字符串的问题一样。鉴于浮点精度的大小小于int类型支持的大小,你不可避免地会发生碰撞。

数学上正确的方法是:

f(x)= 0其中x = 0; f(x)= 1 / x其中x> 0和x&lt;限制(限制可能是10000000000,具体取决于您平台的浮动尺寸)

否则你会尝试使用比你更多的值,这是不可能的。

或者,(因为你正在处理图形),如果你想要满足整个整数范围,并且你可以将2个接近的整数舍入到相同的值,你可以将值除以2(或者3或者你想要多少)缩小以适应所需的整个int范围。除以2会使支持的范围加倍。

所以16000和16001都会以1/8000结束。

我想这取决于你的情况,但你不能让500万座位的体育场内有100万人,并希望每个人都有一个独特的座位号码......你会发生碰撞。

答案 4 :(得分:0)

只需将整数转换为浮点数,假设它们的大小相同,这将为每个整数生成一个唯一的浮点数。

int id = 16;    
float f_id = (float) id;

编辑:我刚刚读到你希望浮点数在[0,1]范围内 - 这会大大减少可能的id数量,可能最好只使用整数作为id,而不是浮点数正如你所指出的那样依赖于内存中的表示。

答案 5 :(得分:0)

当整数值由32位表示并且浮点值由32位表示时,显然不可能将每个可能的整数映射到唯一的浮点数。简单的解决方案是使用双精度值或值的短值。

关键是使用浮点类型,significand的位数多于整数类型。