Forum: Mikrocontroller und Digitale Elektronik PIC32MX370 - Multiplikation


von Hurra (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Problem:

Meiner Logik nach müsste eigentlic die folgende Zeile
1
    int64_t result = a * b;

das gleiche Ergebnis liefern, wie
1
     int64_t result = (int64_t)a * (int64_t)b;

Das ist aber in der Praxis nicht so, die obere Zeile liefert:
2147272840 * -812214784 = -1792036864 = falsch
In Hex: 0xFFFFFFFF952FB000

Laut Handbuch hat der Multiplizierer des PIC das vollständige Ergebnis 
aber berechnet : 32x32bit liefert ein 64Bit Ergebnis, welches der 
Compiler nur lesen muss.

Wie teile ich dem Compiler mit, dass er sich das 64-Bit Ergebnis holen 
soll, ohne die Multiplikation in 64Bit machen zu müssen?
Das klappt natürlich, macht die Sache aber langsam. Was wehtut, weil ich 
das für Filter benötige.

von (prx) A. K. (prx)


Lesenswert?

int a, b;
int64_t result = a * b;
ist auf einer Maschine mit 32 Bit "int" eine 32-Bit Multiplikation, 
keine 64-Bit Multiplikation. Der Typ des Ergebnisses des "*" Operators 
ist nicht vom Typ links von "=" abhängig, sondern nur vom Typ der 
Operanden.

Der Rest hängt vom Compiler ab. Vielleicht gibts ein Builtin, vielleicht 
ist es der GCC und dann gehts per asm Statement.

: Bearbeitet durch User
von Hurra (Gast)


Angehängte Dateien:

Lesenswert?

A. K. schrieb:
> int a, b;
> int64_t result = a * b;
> ist auf einer Maschine mit 32 Bit "int" eine 32-Bit Multiplikation,
> keine 64-Bit Multiplikation. Der Typ des Ergebnisses des "*" Operators
> ist nicht vom Typ links von "=" abhängig, sondern nur vom Typ der
> Operanden.

Danke!
Auf die Idee, sich durch die Hilfe des Compilers zu wühlen, bin ich in 
einem Anfall geistiger Umnachtung natürlich nicht gekommen.

Die Hilfe hat folgendes zu sagen:
"To multiply 32 bits by 32 bits to obtain a 64-bit result, cast the 
32-bit integer to a 64-bit integer (long long) and then perform the 
multiplication operation as follows"
1
Ex:
2
  long long test (int a, int b)
3
  {
4
    return (long long) a * b;
5
    // Same as (long long) a * (long long) b
6
    // NOT the same as (long long) (a * b)
7
  }

Blos: Das ist das, was ich ja schon habe.  Anscheinend multipliziert er 
weiter 64Bit (siehe Anhang). Vermutlich deshalb, weil Optimierungsstufe 
1 beim XC32 das Maximum bei der freien Version ist.

Bleibt mir der inline-Assembler. Da muss ich mich erst mal hinsetzen, 
und mir das ansehen. Allerdings hat allein die Compileroptimierung schon 
die Rechenzeit auf 40% heruntergedrückt. Möglicherweise reicht das für 
meine Anwendung ja aus ;-)

Beitrag #5146680 wurde vom Autor gelöscht.
von Frank K. (fchk)


Lesenswert?

Hurra schrieb:
> A. K. schrieb:
>> int a, b;
>> int64_t result = a * b;
>> ist auf einer Maschine mit 32 Bit "int" eine 32-Bit Multiplikation,
>> keine 64-Bit Multiplikation. Der Typ des Ergebnisses des "*" Operators
>> ist nicht vom Typ links von "=" abhängig, sondern nur vom Typ der
>> Operanden.
>
> Danke!
> Auf die Idee, sich durch die Hilfe des Compilers zu wühlen, bin ich in
> einem Anfall geistiger Umnachtung natürlich nicht gekommen.

Hättest Du auch nicht machen müssen. Im C-Standard steht es auch drin. 
Das ist das in C so definierte Veralten und nichts XC32 oder gcc 
spezifisches.

fchk

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.