我正在为计算机科学大学做一些练习,其中一个是关于将int
64 位数组转换为它的双精度浮点值。
理解第一位符号 +/- 非常容易。指数也一样,我们知道偏差是 1023。
我们在使用有效数字时遇到问题。我该如何计算呢?
最后,我想获得这些位所代表的实数。
我正在为计算机科学大学做一些练习,其中一个是关于将int
64 位数组转换为它的双精度浮点值。
理解第一位符号 +/- 非常容易。指数也一样,我们知道偏差是 1023。
我们在使用有效数字时遇到问题。我该如何计算呢?
最后,我想获得这些位所代表的实数。
您可以将这些位加载到与双精度相同大小的无符号整数中,获取该地址并将其转换为 a void*
,然后将其转换为 adouble*
并取消引用。
当然,如果您真的应该解析浮点标准,这可能是“作弊”,但鉴于您到目前为止所陈述的参数,这就是我解决问题的方法。
计算给定 64 位的有效位非常容易。
根据使用 IEEE 754 的wiki 文章,有效数字由前 53 位(从位 0 到位 52)组成。现在,如果您想将具有类似 67 位的数字转换为您的 64 位值,它将通过将值的尾随第 64 位设置为 1 来进行舍入,即使它之前是一位……因为其他 3 位:
11110000 11110010 11111在最后一个字节四舍五入后变为11110000 11110011 ;
因此无需存储第 53 位,因为它的值始终为 1。这就是为什么您只在有效位中存储 52 位而不是 53 位的原因。
现在要计算它,您只需要定位有效数字的位范围 [bit(1) - bit(52)] -bit(0) 始终为 1- 并使用它。
int index_signf = 1; // starting at 1, not 0
int significand_length = 52;
int byteArray[53]; // array containing the bits of the significand
double significand_endValue = 0;
for( ; index_signf <= significand_length ; index_signf ++)
{
significand_endValue += byteArray[index_signf] * (pow(2,-(index_signf)));
}
significand_endValue += 1;
现在你只需要byteArray
在计算之前进行相应的填充,使用这样的函数:
int* getSignificandBits(int* array64bits){
//returned array
int significandBitsArray[53];
// indexes++
int i_array64bits = 0;
int i_significandBitsArray=1;
//set the first bit = 1
significandBitsArray[0] = 1;
// fill it
for(i_significandBitsArray=1, i_array64bits = (63 - 1); i_array64bits >= (64 - 52); i_array64bits--, i_significandBitsArray ++)
significandBitsArray[i_significandBitsArray] = array64bits[i_array64bits];
return significandBitsArray;
}
如果您有对象的字节表示,则可以将字节复制到正确类型的变量的存储中以进行转换。
double convert_to_double(uint64_t x) {
double result;
mempcy(&result, &x, sizeof(x));
return result;
}
您经常会看到类似*(double *)&x
进行转换的代码,但实际上这将始终有效,这是 C 中未定义的行为。