我尝试从modbus转换一个值。 设备显示“-1.0”,返回值为65535(uint16)。 我现在尝试将此值转换为double。 我用不同的演员试过了。 它给了我总是65353.00 :(
我们如何在double中转换负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;
}
答案 0 :(得分:3)
您取uint16
值65535并将其转换为double
。这是65535.0
没有其他有效的期望。
变量tSP
不记得&#34;它的值最初来自double
的值-1.0
。 tSP
是无符号整数值65535
;周期。
我们如何在double中转换负uint值?
没有&#34;负uint值&#34;。 &#34; u&#34;代表无符号,表示负值不在该类型的值域中。
如果您希望使用dRmSP
,请使用dRmSP
,而不是其他具有不同类型和值的变量。
答案 1 :(得分:2)
根据定义,负无符号值不存在。因此,您无法将其转换为任何内容。
您的实际情况是 - 在从您的设备获取数据时 - -1.0
的值首先转换为unsigned
值。由于-1.0
超出unsigned
可以表示的值范围,所以逻辑是使用模运算。
这种方式适用于负输入值(如-1.0
)和unsigned
变量,其最大值为65535
(对应于16位unsigned
)是继续添加65536 = 65535 + 1
,直到在0
和65535
之间获得结果。对于-1.0
,这会产生65535.0
的结果。当该值转换为unsigned
时,结果为65535
。
这解释了当您的设备显示65535
时,您获得-1.0
值的原因。
你试图用“回归”做的是反过来的过程。仅将unsigned
转换为double
(因为您)是不够的,因为double
可以表示65535.0
(至少在数值精度的限制范围内)。< / p>
第一步是将您的值转换为double
(将65535
转换为65535.0
,因为double
可以代表这样的值(再次在限制范围内)浮点精度)。
下一步 - 您没有执行 - 要求您需要了解设备实际支持的最小值(或最大值) - 您需要从文档中获取该值。例如,如果您的设备可以表示的最小值为-100.0
(或最大值为65435.0
),那么您可以撤消该过程 - 继续减去65536.0
,直到{{1}之间获得结果为止}和-100.0
。
在代码中,这可以通过
完成65435.0
答案 2 :(得分:0)
首先,没有负的无符号整数值。无符号意味着没有符号位。
你做的是:
uint16 t1(-1.0); // wraps around to positive 65535
auto t2 = static_cast<double>(t1); // turns 65535 to 65535.0 (no wrapping)
如果您希望此功能适用于负值,请使用int
或类似(非无符号整数)类型。但是如果你这样做,那么请记住,你会失去一点价值(如果你使用int16)。