给定一个整数,我想在区间[0,1]中产生一个唯一的浮点数。 (此号码将用作id)。
我发现我遇到的所有函数的问题是它们在用完整数值之前遇到重复。
例如,如果是f(a:int):float = 0.a
,那么f(16000) = 0.16
和f(16001) = 0.16001
。但由于它是浮点数,0.16
和0.16001
可能表示相同。
换句话说,我需要一个函数,不仅可以生成唯一的数字,还可以生成唯一的数字(至少是C ++整数域)。
我知道答案取决于特定环境中整数和浮点的大小,但是如果你能给出一个特定大小的例子,它仍然会有所帮助。
答案 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的位数多于整数类型。