C++ 64位整数到双冲突
我正在查看GitHub上的一个JSON验证库,它使用C++ 64位整数到双冲突,c++,c,double,C++,C,Double,我正在查看GitHub上的一个JSON验证库,它使用double进行所有数字比较(即,在与模式进行比较之前,它将数字作为double从JSON中提取出来,也作为double提取) double具有有限数量的状态,就像uint64\u t一样,这意味着必须存在“冲突”——即两个不同的uint64\u t映射到完全相同的双精度 我的问题是:如何找到映射到同一个double的两个离散整数,以便向GitHub贡献者证明将64位整数转换为double是不安全的 还是我错了,使用double是完全安全的?正
double
进行所有数字比较(即,在与模式进行比较之前,它将数字作为double
从JSON中提取出来,也作为double
提取)
double
具有有限数量的状态,就像uint64\u t
一样,这意味着必须存在“冲突”——即两个不同的uint64\u t
映射到完全相同的双精度
我的问题是:如何找到映射到同一个double的两个离散整数,以便向GitHub贡献者证明将64位整数转换为double是不安全的
还是我错了,使用double是完全安全的?正如@user202729所指出的,只要两个整数共享相同的小数位,就会导致双重冲突:
#include <iostream>
using namespace std;
int main() {
uint64_t x = 99999999999999997;
uint64_t y = 99999999999999999;
double a = x;
double b = y;
cout << to_string(x == y) << " " << to_string(a == b) << endl;
}
碰撞示例:
#include <iostream>
using namespace std;
int main() {
uint64_t x = 99999999999999997;
uint64_t y = 99999999999999999;
double a = x;
double b = y;
cout << to_string(x == y) << " " << to_string(a == b) << endl;
}
#包括
使用名称空间std;
int main(){
uint64_t x=9999999999 7;
uint64_t y=99999999999;
双a=x;
双b=y;
无法1
理解double
的规范(尾数为53位,包括隐藏位)2
只询问您是否仍然被卡住……您是如何得出碰撞必须存在的假设的?@UlrichEckhardtdouble
是64位,uint64\u t
是64位,但double可以表示比uint64\u t
更大范围内的整数,因此碰撞必须存在exist@user202729我找到了,但我找不到任何冲突的例子或如何找到冲突的例子。你有什么具体的术语推荐给谷歌吗?啊,所以基本上任何大于2^53
的整数都会导致双重冲突。这就是为什么“好”库只有在发现需要时才会切换到浮点。不过,最终,任何非bignum支持的库都会失败,因为。因此,它们都会根据实际情况做出不同程度的妥协。(您可能希望在回答中添加此细节。)