Forum: Mikrocontroller und Digitale Elektronik subtraction zweier uinsigned 64bit typen


von dingdong (Gast)


Lesenswert?

Hallo,

ich muss zwei unsigned 64bit zahlen die als struct in uint8_t typen 
vorliegen subtrahieren.

Das  addieren ist mir so gelungen.
1
    uint16_t partial;
2
3
    partial = a->word0 + b->word0;
4
5
    resultUID->word0 = partial & 0x00FF;
6
    partial = (partial >> 8) + a->word1 + b->word1;
7
    resultUID->word1 = partial & 0x00FF;
8
    partial = (partial >> 8) + a->word2 + b->word2;
9
    resultUID->word2 = partial & 0x00FF;
10
    partial = (partial >> 8) + a->word3 + b->word3;
11
    resultUID->word3 = partial & 0x00FF;
12
    partial = (partial >> 8) + a->word4 + b->word4;
13
  resultUID->word4 = partial & 0x00FF;
14
  partial = (partial >> 8) + a->word5 + b->word5;
15
  resultUID->word5 = partial & 0x00FF;
16
  partial = (partial >> 8) + a->word6 + b->word6;
17
  resultUID->word6 = partial & 0x00FF;
18
  partial = (partial >> 8) + a->word7 + b->word7;
19
  resultUID->word7 = partial & 0x00FF;
20
  
21
  /* if the result overflowed, return nonzero */
22
  return (partial >> 8);

Das carry wird immer wieder übertragen.  Wie man subtrahiert ist mir im 
Prinzip bekannt und das klappt auch auf Papier nur das umsetzen im C 
Code fällt mir schwer. könnte mir jemand dabei helfen ? Im Prinzip muss 
man bloß anderes herum denken.

von Karl M. (Gast)


Lesenswert?

Hallo,

ohne jetzt den Code überprüft zu haben, ich lasse das meinen Compiler 
direkt für mich machen uint64_t, oder schreibe mir eine einfache 
Assembler Version für addieren und subtrahieren.

von dingdong (Gast)


Lesenswert?

Hallo das geht leider nicht da keine 64bit Typen unterstützt werden. 
Dieser müsste die gleichen Operationen bewältigen.

Ich muss Adressen subtrahieren die als 64bit vorliegen.

von Karl M. (Gast)


Lesenswert?

Hi,

und was ist mit einem uint32_t Datentyp, damit hätte man dann schon mehr 
erledigt.

von dingdong (Gast)


Lesenswert?

Auch in bin blöd ;)

man subtrahiert a-b in einen signed 16bit type legt eine Maske mit 0xFF 
drüber und weißt das result->word0 zu.

dann prüft man mit 0x8000 das signed bit und subtrahiert beim nächsten 
a-b-0xff00 von der Differenz    usw usw ..

von dingdong (Gast)


Lesenswert?

1
int16_t diff=0;
2
  
3
  diff=a->word0-b->word0;
4
  resultUID->word0=diff&0x00FF;
5
  diff=a->word1-b->word1-(diff&0xFF00);
6
  resultUID->word1=diff&0x00FF;
7
  diff=a->word2-b->word2-(diff&0xFF00);
8
  resultUID->word2=diff&0x00FF;
9
  diff=a->word3-a->word3-(diff&0xFF00);
10
  resultUID->word3=diff&0x00FF;
11
  diff=a->word4-b->word4-(diff&0xFF00);
12
  resultUID->word4=diff&0x00FF;
13
  diff=a->word5-b->word5-(diff&0xFF00);
14
  resultUID->word5=diff&0x00FF;
15
  diff=a->word6-b->word6-(diff&0xFF00);
16
  resultUID->word6=diff&0x00FF;
17
  diff=a->word7-b->word7-(diff&0xFF00);
18
  resultUID->word7=diff&0x00FF;
19
  
20
  if(diff)return 1;
21
  
22
  return 0;

kurz getestet scheint zu funktionieren.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

... wenn jetzt wieder Jemand behauptet, daß Assembler schwer wäre ...
8 Rechenoperationen a 1 Takt - man braucht halt 16 Register in der 
Zwischenzeit :/, was durch PUSH und POP wohl auch den einen oder anderen 
Takt brauchen wird.

MfG

von Darth Moan (Gast)


Lesenswert?

Moin,

man haette die Subtraktion auch als Addition machen koennen.
Invertieren, addieren, +1, fertig. So wird das ja wohl auch in
"echten" (also HW) Rechenwerken umgesetzt.

Aber wozu sollte man 16 Register benoetigen?
Man wuerde doch (wenn es denn unbedingt byteweise sein muss)
byteweise rechnen und wegschreiben, oder?
Wenn man unbegrenzt Register hat und die Speichertransfers
in Register-Gruppen exorbitant schneller waeren als einzeln,
dann OK.

von dingdong (Gast)


Lesenswert?

Mal lachen -> es funktioniert so nicht und keinen fiel das auf.

A: ist diff=a->word3-a->word3-(diff&0xFF00); nen Fehler drin und 
zweitens wird das borrow und die Differenz nicht berücksichtigt. Also 
nicht korrekt.

Was funktioniert so lange wie nicht negative wird. Keine Ahnung auf.

Hmm ja man könnte die Additions Funktionen  benutzen :).

Keine Ahnung warum ich an so was simples scheitere man hat sich zu sehr 
daran gewöhnt das alles im Hintergrund abläuft.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.