C/C++;相当于Java';s doubleToRawLongBits()
在Java中,Double.doubleToLongBits()用于实现C/C++;相当于Java';s doubleToRawLongBits(),java,c++,c,Java,C++,C,在Java中,Double.doubleToLongBits()用于实现hashCode()方法 我尝试在C++中做同样的事情,写我自己的代码> DouButToWaLangBITH()/Cuth>方法,在搜索谷歌之后,我找不到合适的实现。 我可以从std::frexp(numbr,&exp)中获取符号和指数,并可以确定符号,但无法确定如何使用按位运算符来获取Java等效值 例如,Java的Double.doubleToLongBits()为Double 3.94返回以下内容: 46160545
hashCode()
方法
<>我尝试在C++中做同样的事情,写我自己的代码> DouButToWaLangBITH()/Cuth>方法,在搜索谷歌之后,我找不到合适的实现。
我可以从std::frexp(numbr,&exp)
中获取符号和指数,并可以确定符号,但无法确定如何使用按位运算符来获取Java等效值
例如,Java的Double.doubleToLongBits()
为Double 3.94返回以下内容:
4616054510065937285
谢谢你的帮助
格雷厄姆
下面是从Double.doubleToRawLongBits()复制和粘贴的文档
一个简单的演员阵容可以:
double d = 0.5;
const unsigned char * buf = reinterpret_cast<const unsigned char *>(&d);
for (unsigned int i = 0; i != sizeof(double); ++i)
std::printf("The byte at position %u is 0x%02X.\n", i, buf[i]);
(在C语言中,表示演员的(const unsigned char*)(&d)
)
更新:要创建具有相同位的整数,必须先创建整数,然后复制:
unsigned long long int u;
unsigned char * pu = reinterpret_cast<unsigned char *>(&u);
std::copy(buf, buf + sizeof(double), pu);
无符号长整型;
无符号字符*pu=重新解释强制转换(&u);
标准:复印件(buf,buf+sizeof(双),pu);
为此,您必须记住几件事:整数的大小必须足够大(对于sizeof(double)\include的静态断言)
静态内联uint64_t双字节(双x){
uint64位;
memcpy(&bits,&x,sizeof bits);
返回位;
}
我喜欢这种类型的工会
union double_and_buffer {
double d;
unsigned char byte_buff[ sizeof(double) ];
} dab;
dab.d = 1.0;
for ( int i = 0; i < sizeof(dab.byte_buff); ++i )
{
cout << hex byte_buff[ i ];
}
联合双\u和\u缓冲区{
双d;
无符号字符字节_buff[sizeof(double)];
}dab;
dab.d=1.0;
对于(int i=0;i w/C的主要问题是双二进制形式是未定义的。这假设双二进制的大小是64位,这不一定如此。@RobK:当然。但是在double
没有映射到IEEE-754double的平台上,位表示不太可能对期望这样的程序非常有用。从hashcode的提到()函数在最初的问题中,他似乎只想要表示double的唯一位字符串,以便在哈希函数或类似的函数中使用。是的,例如,Point3D对象的hashCode()可以用Java编写;事实上,可以使用NetBeans轻松地自动生成:public int hashCode(){int hash=3;hash=59*hash+(int)(Double.doubleToLongBits(this.mx)>>32));hash=59*hash+(int)(Double.doubleToLongBits(this.my)^(Double.doubleToLongBits(this.my)>>32));hash=59*hash+(int)(Double.doubleToLongBits(this.mz)^(Double.doubleToLongBits(this.mz)>>32));return hash;}使用memcpy()对上述doubleToRawBits()进行排序对于3.94的示例,给出了与Java完全相同的结果。这也是最简单的解决方案。我经常使用这种方法,但请注意,除非显式禁用基于类型的别名分析,否则当前的许多编译器都会破坏它。@StephenCanon我知道,从理论上讲,读取未设置的联合成员是未定义的行为,但是真的有一个编译器会为这样一个广为人知且被广泛使用的习惯用法制造问题吗?@Voo:多年来已经出现了好几个问题;最值得注意的是,在4.1左右的某个地方出现了一系列GCC版本。这是未定义的行为。本页上的其他解决方案都是正确的。微软在其API中到处都使用这种结构,例如我USB_HUB_CAP_标志中的状态。该标准要求“联合的大小足以包含其最大的非静态数据成员。每个非静态数据成员的分配就像它是结构的唯一成员一样。联合对象的所有非静态数据成员具有相同的地址”(,第9.5节)因此,以这种方式使用并集实际上需要等同于对所需变量的地址重新解释_cast(),并从const unsigned char*buf生成long?
unsigned long long int u;
unsigned char * pu = reinterpret_cast<unsigned char *>(&u);
std::copy(buf, buf + sizeof(double), pu);
#include <stdint.h>
static inline uint64_t doubleToRawBits(double x) {
uint64_t bits;
memcpy(&bits, &x, sizeof bits);
return bits;
}
union double_and_buffer {
double d;
unsigned char byte_buff[ sizeof(double) ];
} dab;
dab.d = 1.0;
for ( int i = 0; i < sizeof(dab.byte_buff); ++i )
{
cout << hex byte_buff[ i ];
}