在这里运行“CODESYS V3.5 SP16”,我正在尝试实现中提到的哈希码算法
并且必须构建我自己的解决方案来复制 Java Float.floatToIntBits(f)
,从而产生以下功能
FUNCTION F_lrealToLintBits : LINT
VAR_INPUT
lrVal : LREAL;
END_VAR
VAR
arrBytes : ARRAY[0..7] OF BYTE; // LREAL contains 64 bits and each byte contains 8 bits
pVal : POINTER TO LREAL := ADR(arrBytes);
diIndx : DINT;
uiExpt : UINT := 0; // exponent goes from 0 to 63
END_VAR
pVal^ := lrVal; // maps LREAL to array of bytes
// little endian? cause it seems that least significant bit is at lowest address
FOR diIndx := LOWER_BOUND(arrBytes, 1) TO UPPER_BOUND(arrBytes, 1) BY 1 DO
// bit access seems to be manual only so no loops
IF arrBytes[diIndx].0 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].1 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].2 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].3 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].4 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].5 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].6 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
IF arrBytes[diIndx].7 THEN
F_lrealToLintBits := F_lrealToLintBits + LREAL_TO_LINT(EXPT(2, uiExpt));
END_IF
uiExpt := uiExpt + 1; // have to increment exponent after every bit
END_FOR
首先,我想知道某个库中是否有一个现有的函数已经这样做了?
我查看了很多地方,包括 OSCAT “Basic, 3.31” 库,但找不到任何类似的东西(即使是我可以链接在一起的一组函数也可以)。
其次,位访问只能手动完成吗?
我更喜欢使用循环,但似乎不可能?BYTE
如果数组中的数据类型从其他类型更改为其他类型(例如) ,是否有一种较少的复制和粘贴方法来访问涉及自动检测位数的位DWORD
?
潜在的替代品
似乎这是工会派上用场的地方,如https://forge.codesys.com/forge/talk/Engineering/thread/02a65a50b2/#e5f4/1911/c524中所述,如果值不是来自外部来源(即无需检查字节序),Float.floatToIntBits(f)
就像
TYPE
U_lrealToRawLintBits :
UNION
lrVal : LREAL;
liVal : LINT;
END_UNION
END_TYPE
// supposed to replicate floatToIntBits() in Java at
// https://github.com/openjdk/jdk/blob/739769c8fc4b496f08a92225a12d07414537b6c0/src/java.base/share/classes/java/lang/Float.java#L775
FUNCTION F_lrealToLintBits : LINT
VAR_INPUT
lrVal : LREAL;
END_VAR
VAR
uLrealToLintBits : U_lrealToRawLintBits; // for interpreting LREAL as base 10 LINT
END_VAR
IF FPU.IsLRealPosInfinity(lrVal) THEN
F_lrealToLintBits := 2139095040; // corresponds to 0x7f800000
ELSIF FPU.IsLRealNegInfinity(lrVal) THEN
F_lrealToLintBits := 4286578688; // corresponds to 0xff800000
ELSIF FPU.IsLRealNaN(lrVal) THEN
F_lrealToLintBits := 2143289344; // corresponds to 0x7fc00000
ELSE
uLrealToLintBits.lrVal := lrVal;
F_lrealToLintBits := uLrealToLintBits.liVal;
END_IF