ralf9
February 2, 2022, 4:47pm
1
Hallo,
beim Übernehmen von Code zur crc Berechnung von einem Arduino zum MapleMini bin ich auf ein Problem mit dem ~ Operator gestoßen, daß ich nicht verstehe.
Damit kann ich das Problem nachstellen.
Testen kann man es z.B. mit
https://www.tutorialspoint.com/compile_c_online.php
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
int main()
{
bool isnotEqual;
uint16_t ic;
uint16_t crc = 0x2233;
uint8_t byte_h = 0xdd;
uint8_t byte_l = 0xcc;
printf(" crc = %x\n", crc);
ic = ~crc;
printf("~crc = %x\n", ic);
printf("byte_h shifted => %x\n\n", byte_h<<8);
//--- Fall 1 not ok
isnotEqual = ( (~crc) != (byte_h << 8 | byte_l) );
printf("isnotEqual = %u \n", isnotEqual);
//--- Fall 2 ok
isnotEqual = ( ic != (byte_h << 8 | byte_l));
printf("isnotEqual = %u \n", isnotEqual);
//--- Fall 3 ok
isnotEqual = ( (uint16_t)(~crc) != (byte_h << 8 | byte_l));
printf("isnotEqual = %u \n", isnotEqual);
return 0;
}
$gcc -o main *.c -lm
$main
crc = 2233
~crc = ddcc
byte_h shifted => dd00
isnotEqual = 1
isnotEqual = 0
isnotEqual = 0
Mit einem cast vor (~crc) funktionierts auch (Fall 3), nur warum brauch ich da ein cast (uint16_t), wenn crc schon uint16_t ist?
Gruß Ralf
J-M-L
February 2, 2022, 5:01pm
2
byte_h ist "negativ", wenn es zu einem int hochgestuft wird
void setup() {
bool isnotEqual;
uint16_t ic;
uint16_t crc = 0x2233;
uint8_t byte_h = 0xdd;
uint8_t byte_l = 0xcc;
Serial.begin(115200); Serial.println();
Serial.print("crc = 0x"); Serial.println(crc, HEX);
ic = ~crc;
Serial.print("~crc = 0x"); Serial.println(ic, HEX);
Serial.print("byte_h bin => 0b"); Serial.println(byte_h, BIN);
Serial.print("byte_h shifted => "); Serial.println(byte_h << 8, HEX);
Serial.print("byte_h shifted and or-ed => "); Serial.println((byte_h << 8 | byte_l), HEX);
}
void loop() {}
➜
crc = 0x2233
~crc = 0xDDCC
byte_h bin => 0b11011101
byte_h shifted => FFFFDD00
byte_h shifted and or-ed => FFFFDDCC
Die Rechnungen werden bei C++ standardmäßig immer als int ausgeführt. Beim mapleMini ist das ein 32Bit int. Der Typ der Variable wird immer erst bei der Zuweisung berücksichtigt. Deshalb ist für Berechnung/Vergleich erstmal egal welcher Typ crc ist. ~crc ist eine Berechnung, das Ergebnis also 32Bit lang. Da musst Du den Typ explizit angeben, wenn er berücksichtig werden soll.
ralf9
February 2, 2022, 8:33pm
4
Danke, damit wird es klarer.
J-M-L Jackson
Da verhält sich der MapleMini, wie vermutet, anders:
crc = 0x2233
~crc = 0xDDCC
byte_h bin => 0b11011101
byte_h shifted => DD00
byte_h shifted and or-ed => DDCC
MicroBahner
Beim mapleMini ist das ein 32Bit int.
Wird dann bei "uint32_t crc" intern mit uint32_t gerechnet?
Wenn ich bei meinem Beispiel crc als uint32_t und byte als uint16_t definiere, dann passen alle 3 Fälle
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
int main()
{
bool isnotEqual;
uint32_t ic;
uint32_t crc = 0x11223344;
uint16_t byte_h = 0xeedd;
uint16_t byte_l = 0xccbb;
printf(" crc = %x\n", crc);
ic = ~crc;
printf("~crc = %x\n", ic);
printf("byte_h shifted => %x\n\n", byte_h<<16);
//--- Fall 1 ok
isnotEqual = ( (~crc) != (byte_h << 16 | byte_l) );
printf("isnotEqual = %u \n", isnotEqual);
//--- Fall 2 ok
isnotEqual = ( ic != (byte_h << 16 | byte_l));
printf("isnotEqual = %u \n", isnotEqual);
//--- Fall 3 ok
isnotEqual = ( (uint32_t)(~crc) != (byte_h << 16 | byte_l));
printf("isnotEqual = %u \n", isnotEqual);
return 0;
}
Ist es dann so korrekt?
isnotEqual = ( (uint16_t)(~crc) != (byte_h << 8 | byte_l));
Wenn du dich nicht auf dein verwirrendes Beispiel mit
uint32_t crc = 0x11223344;
uint16_t byte_h;
beziehst, sondern auf den Anfangs-Post #1 , dann ja. Genau das cast passiert ja durch deine Hilfsvariable ic
.
system
Closed
August 2, 2022, 10:22am
6
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.