[英]Typecasting uint64 into double precision
I'm receiving a list of bytes, in an array called "info," into the subroutine shown below.我在下面显示的子例程中接收到一个名为“信息”的数组中的字节列表。 They were received serially and gathered up into the array.他们被串行接收并聚集到阵中。 Elements [6] - [13] of the array represent one double precision number.数组的元素 [6] - [13] 表示一个双精度数。 They were necessarily split into individual bytes for serial transmission.它们必须被分成单独的字节以进行串行传输。 The method I'm using to concatenate and convert this list of bytes into a single double precision quantity is, I think, pretty standard.我认为,我用来连接此字节列表并将其转换为单个双精度数量的方法非常标准。
The number 0x3FE3333333333333, expressed as a uint64 type should be 0.6 (decimal) when converted to double.表示为 uint64 类型的数字 0x3FE3333333333333 转换为双精度时应为 0.6(十进制)。 Decimal 0.6 is the torque setpoint for a motor control scheme.十进制 0.6 是电机控制方案的扭矩设定值。 I am, however, seeing the number 4.17232506e-08 (decimal), when the number is converted in this program.但是,当在此程序中转换数字时,我看到数字 4.17232506e-08(十进制)。 Can anyone tell me what's gone wrong here?谁能告诉我这里出了什么问题? Here's the code:这是代码:
void
put_speed_and_torque_together(Uint8 *info, Uint32 crc_rx, Uint32 crc_calc)
// ***************************************************************************************
// * Procedure Name: put_speed_and_torque_together
// * Purpose: Combine separate bytes of Speed Setting and Torque setting
// * into Uint32 and double-precision
// * data types, respectively.
// * Call assign_rx_to_struct.
// * Date created: 04/01/2021
// * By: DDR
// ***************************************************************************************
{
Uint64 temp_word;
Uint32 speed_setpoint;
double torque_setpoint;
if (crc_rx == crc_calc) // If CRC checks out...
{
// Combine group of 4 bytes representing speed_setpoint into one 32-bit word.
speed_setpoint = ((Uint32)info[17])<<24 | ((Uint32)info[16])<<16 | ((Uint32)info[15])<<8 | (Uint32)info[14];
set_SpeedSetpoint(speed_setpoint); // Using sets and gets to protect these variables.
// Concatenate 8 bytes representing torque_setpoint into one word (temp_word).
temp_word = ((Uint64)info[13])<<56 | ((Uint64)info[12])<<48 | ((Uint64)info[11])<<40 | ((Uint64)info[10])<<32 | ((Uint64)info[9])<<24 | ((Uint64)info[8])<<16 | ((Uint64)info[7])<<8 | (Uint64)info[6];
torque_setpoint = *(double*)&temp_word;
// Reading from right to left...
// Point to location of temp_word ("&temp_word" is a pointer).
// Typecast the pointer to the double type (double*).
// Retrieve the contents of the converted pointer (*).
// Assign that value to torque_setpoint (torque_setpoint =).
set_TorqueSetpoint(torque_setpoint); // Using sets and gets to protect these variables.
assign_rx_to_struct(speed_setpoint, torque_setpoint);
}
else
{
InitArrays(); // Clear all relevant data. @@
// Obviously something went wrong here.
// Should I send some kind of message to LCD?
}
} // End put_speed_and_torque_together
The number 0x3FE3333333333333, expressed as a uint64 type should be 0.6...数字 0x3FE3333333333333,表示为 uint64 类型应该是 0.6...
I am, however, seeing the number 4.17232506e-08 (decimal)但是,我看到的是数字 4.17232506e-08(十进制)
Can anyone tell me what's gone wrong here?谁能告诉我这里出了什么问题?
Yes.是的。 Somewhere , code is accessing data as a float
and not a double
.在某处,代码以float
而不是double
的形式访问数据。
int main() {
union {
uint64_t u64;
float f[2];
double d;
} x;
x.u64 = 0x3FE3333333333333;
printf("%-24a %-24.17g 0x%016llX %.8e %.8e\n",
x.d, x.d, (1ULL * x.u64), x.f[0], x.f[1]);
}
Output Output
// v- expected ------v v- seen -----v
0x1.3333333333333p-1 0.59999999999999998 0x3FE3333333333333 4.17232506e-08 1.77499998e+00
This is not an endian issue.这不是字节序问题。
Tip: with such FP bit-dibbling, report double
with "%a"
and/or "%.16e"
.提示:对于这样的 FP bit-dibbling,用"%a"
和/或"%.16e"
报告double
。
"4.17232506e-08" lacked informative digits. “4.17232506e-08”缺少信息数字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.