0

一个功能块给了我一些数据类型 REAL。Real 必须转换为 DWORD。在使用的平台上,数据类型具有以下大小:

  • 实数:32 位(4 字节)
  • DWORD:32 位(4 字节)

因此,我认为如果仅在这两种数据类型之间传输位表示,则该值不会改变或降低精度。我想做的是以下几点:

myReal : REAL;
myDWord : DWORD;
myResultReal : REAL;

myReal := 0.819;

myDWord := REAL_TO_DWORD(myReal);
myResultReal := DWORD_TO_REAL(myDWord);

// myResultReal has value: 1
// Also when I check the bit string of the myDWord it differs from the actual
// bit string of myReal. Immediately after the first conversion.

整个问题只是编程语言的规则。由于两种数据类型具有相同的内存大小,因此似乎完全没有必要进行转换。转换的实际原因只是因为我需要稍后将我的数字传递给代码,它只接受 DWORD 数据类型。然后它使用 DWORD 来获得一个 REAL,但此时该值受到了不希望的影响。

4

3 回答 3

0

有两种选择。更高级的是pboedker建议的:UNION 数据类型。

例子:

TYPE U_TestUnion :
UNION
    Value_DWORD : DWORD;
    Value_REAL  : REAL;
END_UNION
END_TYPE   

VAR
    TestUnion   : U_TestUnion;
END_VAR

 TestUnion.Value_REAL := 0.819;
 //TestUnion.Value_DWORD is now 1062316540 (=16#3F51A9FC)

 TestUnion.Value_DWORD := 10; 
 //TestUnion.Value_REAL is now 1.401298E-44 

 TestUnion.Value_DWORD := 1062316540; 
 //TestUnion.Value_REAL is now 0.819 

另一个是使用 MEMCPY 函数,它将值从内存复制到其他位置。该函数在不同的系统中可以命名略有不同。通过这样做,您可以将内容从 REAL 值的位置复制到 DWORD 的地址并向后复制。

在 REAL->DWORD 方向,应该不用担心。但是当从 DWORD 复制到 REAL 时,如果数据有可能在任何地方被修改,则可能会出现一些问题。该值可能是NaNInfinity,这可能会导致 PLC 崩溃。这意味着 REAL 不是格式正确的十进制数。

VAR
    Value_DWORD : DWORD;
    Value_REAL  : REAL;
END_VAR

Value_REAL := 0.819;
MEMCPY(destAddr:=ADR(Value_DWORD), srcAddr:=ADR(Value_REAL), n:=SIZEOF(Value_REAL));
 //Value_DWORD is now 1062316540 (=16#3F51A9FC)

Value_DWORD := 10; 
MEMCPY(destAddr:=ADR(Value_REAL), srcAddr:=ADR(Value_DWORD), n:=SIZEOF(Value_DWORD));
 //Value_REAL is now 1.401298E-44 

Value_DWORD := 1062316540; 
MEMCPY(destAddr:=ADR(Value_REAL), srcAddr:=ADR(Value_DWORD), n:=SIZEOF(Value_DWORD));
 //Value_REAL is now 0.819 
于 2018-10-12T11:36:57.720 回答
0

问题是您正在使用转换,因此您的 REAL=0.819 将转换为 DWORD=1 并返回为 REAL=1。位表示将在每次转换时相应更改。

解决您的问题的方法是使用 UNION (IEC 61131-3)。这样,您可以写入 REAL 部分,将 DWORD 部分传递给其他代码,然后再次在该代码中使用 REAL 部分。

于 2018-10-12T10:14:06.793 回答
0

一个简单的解决方案是在转换之前将实际值乘以 10 n 倍,具体取决于您想要的精度,如下所示:

myReal := 0.819;

myDWord := REAL_TO_DWORD(myReal * 1000);
myResultReal := DWORD_TO_REAL(myDWord)/1000;

在此处输入图像描述

于 2018-10-13T04:54:56.547 回答