C: schnelle Integer-Division Multiplikation mit 10^6

Beitrag #4966088 wurde von einem Moderator gelöscht.
Beitrag #4966094 wurde von einem Moderator gelöscht.
Beitrag #4966115 wurde von einem Moderator gelöscht.
Gast #4966116
Lesenswert?

Wolfgang schrieb:
> M.m schrieb:
>> wie teilt/multipliziert ich am schnellsten in C einen Integer 32Bit mit
>> 1000000?
>
> Du wirst du entscheiden müssen.
> Multiplikation und Division können sehr unterschiedlich lange brauchen.
>
> Und natürlich hängt es von deiner Hardware ab.

Ich frag mich ob die Multiplikation durch Shifts schneller sei als 
einfach x*/10^6 zu schreiben?
Gast #4966126
Lesenswert?

auch wenn es ein troll ist.

Hab dazu auch mal ne frage.

Kann mir jemand ein Buch empfehlen, welches so die gängigen/bekannten 
Algos für so die verschiedenen Rechnungen enthält?

Z.B. wie man eine Division implementiert für aneinander gereite 
ints/bytes.
Da ist mir letztes nur die schriftliche Division eingefallen.

Oder z.B. der Cordic und was weis ich was es noch alles gibt.

Float nach String etc.
Gast #4966133
Lesenswert?

Allenfalls kann man sich ueberlegen ob die Zahl wirklich genau 1'000'000 
sein muss, oder ob 1'048'576, dh 5% mehr auch passen wuerde. Das waere 
dann 2^20, resp schieben um 20 bit nach links oder rechts.
#4966138
Lesenswert?

M.m schrieb:
> Wolfgang schrieb:
>>
>> Und natürlich hängt es von deiner Hardware ab.
>
> Ich frag mich ob die Multiplikation durch Shifts schneller sei als
> einfach x*/10^6 zu schreiben?

Zumindest letzteres wird weder Speicher noch Laufzeit brauchen.
Das wird zur Compiletime zu einer Fehlermeldung.

Um Andrei Alexandrescu zu zitieren: "learn to know your hardware"

Multiplizieren kann man per HW 64x64 Bit in einem Takt (Chipfläche 
egal).
Division dagegen wird oft durch Muktiplikation mit dem Kehrwert 
erledigt, wobei der Kehrwert interativ ermittelt.
Wenn der Teiler aber fix ist (1000000), dann kann man (10^-6 << 
Wortbreite) multiplizieren und nur den oberen Teil des Ergebnisses 
benutzen. Und schon braucht mal nur den (hoffentlich Hw-)Multiplizierer.
Beitrag #4966145 wurde von einem Moderator gelöscht.
Gast #4966152
Lesenswert?

MaWin schrieb im Beitrag #4966145:
> Hier läuft ein Genie nach dem anderen auf. Unglaublich diese geballte
> Inkompetenz.

Es haben sich schon Leute halb tot gerechnet, um Messdaten auszuwerten, 
die mit einer Genauigkeit von schlechter als ein Promille gemessen 
wurden. Wenn der TO vernünftige Randbedingungen angeben würde, ...

Garbage in - Garbage out
Beitrag #4966159 wurde von einem Moderator gelöscht.
Beitrag #4966164 wurde von einem Moderator gelöscht.
Beitrag #4966242 wurde von einem Moderator gelöscht.
#4966275
Lesenswert?

... wenn ich jetzt noch eine Begründung erhalten könnte, was an meinem 
Post eine Löschung rechtfertigt?

Ok, unterschwellig war Der nicht Ohne ... gebe ich ja zu.
Zumindest im ersten Teil.

Im zweiten Teil, wo ich auf den kritisierten Ansatz eingehe, war aber 
weder böse, noch themenfern.

Soll das Niveau hier auf 'Ihr seid Alle inkompetent' runtergeregelt 
werden?

Zumindest wurden große Buchstaben und Satzzeichen benutzt, der deutschen 
Sprache also durchaus mächtig und durchaus bereit, halbwegs lesbare 
Posts abzugeben - trotzdem finde ich den Ton ... naja, ich schrieb ja 
bereits was dazu, Was wohl nicht sonderlich Gefallen gefunden hatte.

-----------------------------------------

Zurück zum kritisierten Ansatz, mit 5% Differenz einfach nur zu shiften:
Wenn ich damit Rechenzeit spare, kann ich zumindest in die Richtung 
überlegen.
Vll. fällt mir ja auch was ein, womit ich den Fehler im Vorfeld bereits 
positiv beeinflussen kann, daß ich eben näher an das geforderte Ergebnis 
durch shiften komme, als durch das Teilen durch 10^6.

MfG

@Mod
Sollte auch dieser Post Dir nicht sonderlich gefallen, kürze Ihn doch 
bitte entsprechend ein.
Gast #4966312
Lesenswert?

Ohne Multiplizierer sowas evt.?
1
uint32 mul1000(uint32 x)
2
{
3
uint32 y = x<<10;
4
  
5
 
6
   x<<=3;
7
   /* inclusive lustiger Überläufe bei größeren x */
8
   y-=x;
9
   y-=x;
10
   y-=x;
11
   return y;
12
}
13

14

15
main()
16
{
17
uint32 x=getAnyX();
18

19

20
   x=mul1000(x);
21
   x=mul1000(x);
22

23
}
#4966328
Lesenswert?

Achim S. schrieb:
> Ohne Multiplizierer sowas evt.?

Falls kein Barrellshifter vorhanden besser:
1
uint32 mul1000(uint32 x)
2
{
3
  uint32 y;
4
  // nur 10 Shifts
5
  x = x << 3;
6
  y = x << 7;
7

8
  /* inclusive lustiger Überläufe bei größeren x */
9
  y-=x;
10
  y-=x;
11
  y-=x;
12
  return y;
13
}
Aber falls es den in 32-Bit breit gibt, dann gibt es meist 
32x32-Multiplier
Gast #4966352
Lesenswert?

M.m schrieb:

> für value * 10^6 kann man ja 6 mal folgendes ausführen.
> value * 10 = (value << 3) + value << 1

Kann man.

Man kann sich auch ueberlegen, dass 10^6 = 2^6 * 5^6 gilt.
5^6 ist aber 25^3. 25 ist 33 - 8; 33 ist 32 + 1.

Also: value*25 = value*32 - value*8 + value

Noch krasser ist, dass 5^3 = 125 = 128 - 3 gilt.

Also: value*125 = value*128 - value*4 + value
Das machst Du zwei mal; anschlieszend mit 64
malnehmen. Fertsch.
#4966356
Lesenswert?

M.m schrieb:
> für value * 10^6 kann man ja 6 mal folgendes ausführen.
> value * 10 = (value << 3) + value << 1
>
> Für Division wie?

Wie oben irgendwo zu lesen war hat z.B. der ARM-GCC-Port solche C-Tricks 
selber drauf. Und der kennt dann auch die Ziel-HW besser als der 
generische C-Programmierer.

> Für Division wie?
Der nimmt dann schlicht den (fixen) Kehrwert, skaliert auf max. 
Genauigkeit für die vorhandene Ergebnisbreite, multipliziert und schiebt 
die Skalierung wieder zurück:

sebi_s schreibt:
> Hab mir gerade mal den Spaß gemacht und GCC gefragt.
> Auf einem ARM läuft es auf eine Multipliation mit 1125899907
> (mit 64 Bit Ergebnis) und anschließenden Shift um
> 50 Bits nach rechts raus.
also   x 112569907 / 2^50
was ziemlich genau 1/1000000 ist.
Und das macht der Compiler. Jedesmal auf den konkreten Divisor 
optimiert. In wenigen Sekunden.

Es macht heute mehr Sinn, dem Compiler konkret zu sagen, was er tun 
soll, und nicht wie er es machen soll.
Gast #4966386
Lesenswert?

OLEK schrieb:
> Kann mir jemand ein Buch empfehlen, welches so die gängigen/bekannten
> Algos für so die verschiedenen Rechnungen enthält?

https://www.amazon.de/dp/B00CMNTKZ4/

Das haben viele Hochschulen in elektronischer Form oder auch Google 
sollte entsprechende Resultate für einen kurzen Blick in das Buch 
liefern...

Ggf. steht in folgendem Buch auch etwas drin, wobei 10^6 eher relativ 
niedrig ist, im fxtbook sind aber viele low level Geschichten drin mit 
denen man viel optimieren kann, ggf. findet sich da etwas für deine 
Problematik (wobei die eingeworfene Magic Number Lösung doch schon 
relativ elegant ist).

http://jjj.de/fxt/fxtbook.pdf#section.29.1
http://jjj.de/fxt/fxtpage.html
http://jjj.de/fxt/fxtbook.pdf

Fun fact: Der Downloadlink dieses Autors selbst ist bei Google höher 
gerankt als der von Händlern. Mich beschleicht da so das Gefühl, dass 
der Verlag da kaum Profit mit macht.
Moderator (Firma: Titel) Persönliche Seite #4966427
Lesenswert?

Patrick J. schrieb:
> ... wenn ich jetzt noch eine Begründung erhalten könnte, was an meinem
> Post eine Löschung rechtfertigt?
Weil du in diesem Post auf einen Troll reagiert hast. Und sonst 
eigentlich nichts zur Sache drin stand...

> @Mod
> Sollte auch dieser Post Dir nicht sonderlich gefallen, kürze Ihn doch
> bitte entsprechend ein.
Im üblichen Fall werden Posts nicht auf Byteebene bearbeitet. 
Bestenfalls dann, wenn da zwar eine (allgemeine, unterschwellige) 
Beleidigung und sonst neue Informationen drin stehen, wird nur 
partiell gelöscht.
#4966509
Lesenswert?

>Carl Drexler..
>Es macht heute mehr Sinn, dem Compiler konkret zu sagen, was er tun
soll, und nicht wie er es machen soll.

Ja und nein. Wenn man mit 5% Fehler leben kann, daher 20 mal schieben 
reicht verglichen mit was auch immer der Compiler wirres macht...

Die 5% Fehler kann ich mir zB fuer eine Strom-Status Anzeige leisen, 
fuer eine Temperaturanzeige zu einer Temperaturregelung eher nicht.
#4966520
Lesenswert?

Sapperlot W. schrieb:
>>Carl Drexler..
>>Es macht heute mehr Sinn, dem Compiler konkret zu sagen, was er tun
> soll, und nicht wie er es machen soll.
>
> Ja und nein. Wenn man mit 5% Fehler leben kann, daher 20 mal schieben
> reicht verglichen mit was auch immer der Compiler wirres macht...
>
> Die 5% Fehler kann ich mir zB fuer eine Strom-Status Anzeige leisen,
> fuer eine Temperaturanzeige zu einer Temperaturregelung eher nicht.

In dem aufgeführten Beispiel liegt der Fehler nicht bei 5%, was man 
leicht nachrechnen kann, wenn man dazu in der Lage ist und falls man das 
nicht ist sollte man solche Dinge dem Compiler überlassen. Der wurde 
nämlich von Leuten geschrieben, die dazu in der Lage sind.
#4966698
Lesenswert?

Possetitjel schrieb:
> M.m schrieb:
>
>> für value * 10^6 kann man ja 6 mal folgendes ausführen.
>> value * 10 = (value << 3) + value << 1
>
> Kann man.
>
> Man kann sich auch ueberlegen, dass 10^6 = 2^6 * 5^6 gilt.
> 5^6 ist aber 25^3. 25 ist 33 - 8; 33 ist 32 + 1.
>
> Also: value*25 = value*32 - value*8 + value
>
> Noch krasser ist, dass 5^3 = 125 = 128 - 3 gilt.
>
> Also: value*125 = value*128 - value*4 + value
> Das machst Du zwei mal; anschlieszend mit 64
> malnehmen. Fertsch.

Solche Zerlegungen sollte doch der Compiler selber beherrschen (ok, 
vernünftiges Programmieren vorausgesetzt). Wenn jetzt Float verwendet 
wird sieht es wieder anders aus. Aber auch hier haben gute Controller 
FPUs, welche dann entsprechend genutzt werden können.

Bei FPGA und ASIC Design ist es natürlich von Vorteil, wenn man nicht 
nur den Taschenrechner bedienen, sondern solche Zerlegungen selber kann. 
Aber auch hier wird je nach verwendeten Busbreiten schon automatisch mit 
DSP Slices gearbeitet.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren