这可能是一个困难的问题,但我正在尝试执行以下操作:
取一个输入字符串i,我希望它是一个包含毫秒的unix时间戳 将其转换为 int64 字节数组,但我只能使用更简单的结构进行操作,我最大的可用 int 是 32 位,扩展一点这是用于 PLC 向数据库发送一些电报
Wanted input:
"1707461225120" // int64 string
Should return:
[00, 00, 01, 8D, 8C, 9E, AA, A0] // 8 byte array
我并不关心用什么语言来回答,我只关心解决这个问题的逻辑思维,任何东西都会有帮助,没有高级数据类型
我尝试了以下操作(想要将字符串转换为 int64 8 字节数组),很抱歉,如果这是一种奇怪的语言,但它是我所拥有的,对于响应,我不需要相同的格式,我只需要一般逻辑/数学,没有高级数据类型
byArray : Array[0..31] OF Byte; // temp array of characters in string
byArrayO : Array[0..7] OF Byte; // temp memory before converting to output
charCount : Int; // temp amount of characters in input string 16 bit int
il : Int; // temp counter generic 16 bit int
i : String; // input string
o : Array[0..7] OF Byte; // output byte array
// reset temp memory
FOR #il := 0 TO 7 DO
#o[#il] := 0;
#byArrayO[#il] := 0;
END_FOR;
// Convert string to character array
"STRING_TO_CHARS"(Chars => #byArray,
Cnt => #charCount,
pChars := 0,
Strg := #i);
// loop character array, here's what im doing wrong, but unsure how to solve this
FOR #il := 0 TO #charCount - 2 DO // - 2 due to character count offset by 2
// Function adds an int to a byte array
"ADD_BYTE_ARRAY"(iAdd := (#byArray[#il] - 48) * 10 ** #il, // convert int char to int and offset
arr := #byArrayO); // array to add to
END_FOR;
#o := #byArrayO;
通过这篇文章https://stackoverflow.com/a/28201576/23369035我需要调整 add_byte_Array 输入以保留旧 val 值的内存,但是当我无法使用时,如何使用字节数组来完成此操作int64?
Wanted input:
"1707461225120"
Should return:
[00, 00, 01, 8D, 8C, 9E, AA, A0]
What my code does:
adds the characters in the string together one by one :/
我通过将字节数组乘以 int32 值然后加上毫秒来“解决”了我的问题
MULT_BYTE_ARRAY
// Multiply to byte array and carry over
#carry := 0;
FOR #i := #LEN TO 0 BY -1 DO
#sum := BYTE_TO_UDINT(#arr[#i]) * #iMult + #carry;
#carry := SHR(IN := #sum, N := 8);
#arr[#i] := UDINT_TO_BYTE(#sum);
END_FOR;
ADD_BYTE_ARRAY
// Add to byte array and carry over
#carry := #iAdd;
FOR #i := #LEN TO 0 BY -1 DO
#sum := (#arr[#i] & 255) + #carry;
#arr[#i] := UDINT_TO_BYTE(#sum);
#carry := SHR(IN := #sum, N := 8);
END_FOR;
"ADD_BYTE_ARRAY"(iAdd := STRING_TO_UDINT(#i), // regular unix timestamp in
arr := #byArrayO);
"MULT_BYTE_ARRAY"(iMult := 1000,
arr := #byArrayO);
在此之后,我可以使用 ADD_BYTE_ARRAY 添加 ms,当你知道不会有任何溢出时,效果很好
此外,您还可以使用 add 和 mumlt 字节数组来制作 int64_str_to_bytes
FUNCTION "LINT_STR_TO_BYTES" : Void
VAR_INPUT
s : String;
END_VAR
VAR_OUTPUT
bytes : Array[0..#INT64_LEN] OF Byte;
END_VAR
VAR_IN_OUT
END_VAR
VAR_TEMP
c : Int; // count
bytesTemp : Array[0..#INT64_LEN] OF Byte;
strLen : Int;
END_VAR
VAR CONSTANT
INT64_LEN : Int := 7; // 8 bytes in lint
END_VAR
FOR #c := 0 TO #INT64_LEN DO // clear temp
#bytesTemp[#c] := 0;
END_FOR;
#strLen := LEN(#s);
FOR #c := 1 TO #strLen DO
"ADD_BYTE_ARRAY"(arr := #bytesTemp,
iAdd := CHAR_TO_BYTE(#s[#c]) - 48);
IF (#c <> #strLen) THEN
"MULT_BYTE_ARRAY"(arr := #bytesTemp,
iMult := 10);
END_IF;
END_FOR;
#bytes := #bytesTemp;