Forum: Mikrocontroller und Digitale Elektronik C, Dezimal -> Ternärzahl


von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Abend,

ich bräuchte für ein Projekt ein kleines Stück Code, dass mir eine 
Dezimalzahl von 0-200 in einen Ternärcode umwandelt, und zwar in C, 
genauer in dem Dialekt der Arduino IDE, aber da geht ja das meiste, was 
auch in C geht, hoff ich. Ich habe mir jetzt schon stundenlang den Kopf 
zerbrochen, aber ich weiß nicht, wie, kann mir jemand weiterhelfen?
Und eine LUT mit 200 Einträgen wollte ich jetzt auch nicht von Hand 
tippen :/

von Dr. Sommer (Gast)


Lesenswert?

Jeromyo Hochgesang schrieb:
> Dialekt der Arduino IDE
Das ist einfach C++, welches auch alles kann was C kann.

Stelle die Zahl eben zur Basis '3' dar (anstelle zur Basis '2', wie sie 
Computer speichern, oder '10' wie man Zahlen üblicherweise 
menschenlesbar darstellt). Das geht üblicherweise über sukzessives 
Teilen mit Rest durch 3. Schaue mal nach BCD-Encodern, die machen fast 
das selbe, aber zur Basis 10.

von B. S. (bestucki)


Lesenswert?


von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Sehr nett, danke, ist ein guter Anfang :)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

In itoa/utoa kann man doch die Bases (radix) angeben. Damit ist die 
Umwandling ins 3er-System eine C-Zeile.

von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Kannst du mal kurz ein Pseudocode-Beispiel mit itoa geben? Weil ich habs 
damit trotz Recherche nicht hinbekommen

von Markus F. (Gast)


Lesenswert?

Darf man fragen wozu das benötigt wird?

von B. S. (bestucki)


Lesenswert?

Jeromyo Hochgesang schrieb:
> Kannst du mal kurz ein Pseudocode-Beispiel mit itoa geben? Weil ich habs
> damit trotz Recherche nicht hinbekommen

http://www.cplusplus.com/reference/cstdlib/itoa/

von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Ich bastel an einem Verschlüsselungsalgorithmus auf dem AVR, durch den 
Zahlenbasiswechseln und reduzieren von Bitanzahlen wird der ursrüngliche 
Text bei falschem Schlüssel nicht mehr rekonstruierbar, so weit der 
Gedanke, klappt auch ganz gut :)

von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Danke an be stucki!

von Mr. X (Gast)


Lesenswert?

Jeromyo Hochgesang schrieb:
> Kannst du mal kurz ein Pseudocode-Beispiel mit itoa geben? Weil ich habs
> damit trotz Recherche nicht hinbekommen

Brauchst du es auch noch vorcompiliert?

Du kannst auch so lange 81, 27, 9 und 3 von deiner Zahl abziehen, bis 
jeweils etwas negatives raus kommt.

von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Nein, Mr. X, es läuft alles schon so wie geplant :) Tzdm danke, ich habe 
es mit dem sukzessiven Teilen hinbekommen.

von Mr. X (Gast)


Lesenswert?

Jeromyo Hochgesang schrieb:
> sukzessiven Teilen

Und wie lange dauert das im Vergleich zur Subtraktion?

von B. S. (bestucki)


Lesenswert?

Mr. X schrieb:
> Und wie lange dauert das im Vergleich zur Subtraktion?

Hab ich vor einem halben Jahr mal versucht. Um eine Zahl nur durch 
Subtraktion in einen String umzuwandeln, benötigte mein Controller ca. 
1.5 mal länger als mit Modulo und Division. Der benötigte 
Programmspeicher war etwa gleich. Getestet mit einem PIC18 und dem XC8 
Compiler von Microchip. Sourcecode hab ich nicht mehr.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falls Geschwindigkeit zählt, kann man / und % verwenden und den Code auf 
Geschwindigkeit optimieren. Der Compiler verwendet dann eine 
Multiplikation.

Beispiel:
1
unsigned d, m;
2
3
void f (unsigned x)
4
{
5
    d = x / 3;
6
    m = x % 3;
7
}

Ergebnis mit avr-gcc 4.7:
1
f:
2
  movw r30,r24   ;  2  *movhi/1  [length = 1]
3
  movw r18,r24   ;  6  *movhi/1  [length = 1]
4
  ldi r26,lo8(-85)   ;  7  *movhi/5  [length = 2]
5
  ldi r27,lo8(-86)
6
  rcall __umulhisi3   ;  8  *umulhi3_highpart_call  [length = 1]
7
  lsr r25   ;  31  *lshrhi3_const/2  [length = 2]
8
  ror r24
9
  sts d+1,r25   ;  11  *movhi/4  [length = 4]
10
  sts d,r24
11
  movw r20,r24   ;  27  *movhi/1  [length = 1]
12
  lsl r20   ;  32  *ashlhi3_const/2  [length = 2]
13
  rol r21
14
  add r20,r24   ;  20  *addhi3/1  [length = 2]
15
  adc r21,r25
16
  sub r30,r20   ;  21  subhi3/1  [length = 2]
17
  sbc r31,r21
18
  sts m+1,r31   ;  22  *movhi/4  [length = 4]
19
  sts m,r30
20
  ret   ;  30  return  [length = 1]

Und hier noch die 8-Bit Version, nochma kürzer:
1
f:
2
  ldi r25,lo8(-85)   ;  6  movqi_insn/2  [length = 1]
3
  mul r24,r25   ;  7  umulqi3_highpart  [length = 3]
4
  mov r25,r1
5
  clr __zero_reg__
6
  lsr r25   ;  8  *lshrqi3/3  [length = 1]
7
  sts d,r25   ;  9  movqi_insn/3  [length = 2]
8
  mov r18,r25   ;  23  movqi_insn/1  [length = 1]
9
  lsl r18   ;  14  *ashlqi3/3  [length = 1]
10
  add r18,r25   ;  16  addqi3/1  [length = 1]
11
  sub r24,r18   ;  17  subqi3/1  [length = 1]
12
  sts m,r24   ;  18  movqi_insn/3  [length = 2]
13
  ret   ;  26  return  [length = 1]

Was ich nicht verstehe ist, was das mit Verschlüsselung zu tun haben 
soll.

Scheint eher ne Obfuscation zu werden als ne handfeste, seriöse 
Verschlüsselung...

von Jeromyo (Gast)


Lesenswert?

(Sry, gerade als Gast, da fremder Rechner :/)

So hab ich das ganze jetzt gelöst, nicht sehr effizient und für euch 
wahrsch."Spaghetticode", aber was solls, i made it!
1
int dec2TC(int decInt){
2
 
3
 int decIntModulo[5];
4
 int decIntA[5];
5
 
6
 for(int x2 = 0; x2 <= 5; x2++){
7
  decIntModulo[x2] = 0;
8
  decIntA[x2] = 0; 
9
 }
10
 
11
 decIntA[0] = decInt/3;
12
 decIntModulo[0] = decInt % 3;
13
 decIntA[1] = decIntA[0]/3;
14
 decIntModulo[1] = decIntA[0] % 3;
15
 decIntA[2] = decIntA[1]/3;
16
 decIntModulo[2] = decIntA[1] % 3;
17
 decIntA[3] = decIntA[2]/3;
18
 decIntModulo[3] = decIntA[2] % 3;
19
 decIntA[4] = decIntA[3]/3;
20
 decIntModulo[4] = decIntA[3] % 3;
21
 decIntA[5] = decIntA[4]/3;
22
 decIntModulo[5] = decIntA[4] % 3; 
23
 
24
 String sInt = "";
25
 int ternVal = 0b00000;
26
 
27
 for(int x3 = 4; x3 >= 0; x3--){ 
28
 sInt = sInt + decIntModulo[x3];
29
 }
30
 
31
 char charArInt[sInt.length() + 1];
32
 sInt.toCharArray(charArInt, sizeof(charArInt));
33
 ternVal = atoi(charArInt);
34
 
35
 return ternVal;
36
 
37
}

von Jeromyo H. (jeromyo) Benutzerseite


Lesenswert?

Mir fällt gerade auf, das innere, die tatsächliche Division+Modulo, 
könnte man in eine Schleife packen, aber so ists übersichtlicher :)

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Jeromyo Hochgesang schrieb:
> aber so ists übersichtlicher :)
ernsthaft?

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.