将双倍转换为 uint 并重新游览

Convert double to uint and retour

本文关键字:新游览 uint 转换      更新时间:2023-10-16

我尝试从modbus转换一个值。设备显示"-1.0",重新巡回的值为 65535 (uint16(。我现在尝试将此值重新巡回转换为双倍。我用不同的演员试过了。它总是给我 65353.00 :(

我们如何将负 uint 值转换为双倍值?

typedef unsigned short uint16;
int main() {
double dRmSP = -1.0;                       //-1.0000   ok
uint16 tSP = static_cast<uint16>(dRmSP);   // = 65535   ok
// retour
double _dRmSP = static_cast<double>(tSP);  // = 65535.0000  why??
// try
double _dRmSP_ = static_cast<double>(static_cast<int>(tSP));    // =65535.0000  why??
return 0;
}

您将uint16值 65535 转换为double。这是 65535.0。
没有其他有效的期望。

变量tSP不会"记住"其值最初来自值-1.0 doubletSP是无符号整数值65535;时期。

我们如何将负 uint 值转换为双倍值?

没有"负 uint 值"。"u"代表无符号,这意味着负值不在该类型值的域中。

如果您希望使用dRmSP则使用dRmSP,而不是具有不同类型和值的其他变量。

根据定义,负无符号值不存在。 所以你不能把一个转换成任何东西。

您的实际情况是 - 从您的设备获取数据 - -1.0的值首先转换为unsigned值。 由于-1.0超出了unsigned可以表示的值范围,因此逻辑是使用模算术。

对于负输入值(如-1.0(和具有最大值65535unsigned变量(对应于16位unsigned(的工作方式是不断添加65536 = 65535 + 1,直到获得065535之间的结果。 对于-1.0,这会产生65535.0的结果。 当该值转换为unsigned时,结果65535

这就解释了为什么当设备显示-1.0时,您获得的值为 65535

您试图用"重游"做的是逆转该过程。 将unsigned转换为double是不够的(就像您一样(,因为double可以表示65535.0(至少在数值精度限制内(。

第一步是将您的值转换为double(这会将65535转换为65535.0,因为double可以表示这样的值(同样在浮点精度的限制内(。

下一步 - 您没有执行 - 需要了解您的设备实际支持的最小(或最大(值 - 您需要从文档中获取。 例如,如果您的设备可以表示的最小值是-100.0(或最大值是 65435.0 (,那么您反转该过程 - 继续减去65536.0,直到获得 -100.065435.0 之间的结果。

在代码中,这可以通过以下方式完成

double dRmSP = -1.0;                       //-1.0000   ok
uint16 tSP = static_cast<uint16>(dRmSP);   // = 65535   ok
// retour
double dRmSP = static_cast<double>(tSP);  // = 65535.0000  - as described above
while (dRmSP > 65435.0) dRmSP -= 65536.0;   //  voila!  -1.0 obtained

首先,没有负的无符号整数值。无符号表示没有符号位。

你所做的是:

uint16 t1(-1.0); // wraps around to positive 65535
auto t2 = static_cast<double>(t1); // turns 65535 to 65535.0 (no wrapping)

如果您希望这适用于负值,请使用 int 或可比较(无符号整数(类型。但是如果你这样做,那么请记住,你会损失一点值(如果你使用 int16(。