[closed] Division anders durchführen
-
Grüsse zusammen,
Folgendes Problem:
VarA * 1000000 / VarB
Wenn ich
VarA * 1000000
rechne, dann kann es möglich sein, dass es einen Überlauf gibt. Wenn ich zuerst VarA / VarB rechne, dann verliere ich Kommastellen, weil es integrale Typen sind.Wie kann ich diese Rechnung umformulieren, ohne Genauigkeit zu verlieren oder einen Überlauf zu erzeugen?
(Überlauf entsteht irgendwo bei 9 Billionen)Ich hatte ein ähnliches Problem bei der Multiplikation, doch dort habe ich es wohl gelöst. Als Beispiel will ich es mal hier reinsetzen:
Problem war:
VarA * VarB / 1000000
Auch wieder ohne Genauigkeitsverlust oder Überlauf.
Lösung (denke ich):
VarA * (VarB / 1000000) + (VarA / 1000000) * (VarB % 1000000) + ((VarA % 1000000) * (VarB % 1000000)) / 1000000;
Klar, wenn VarB oder VarA genügend gross gewählt wird, dann gibt es immer noch einen Überlauf, aber mit dieser Methode lassen sich deutlich grössere Zahlen miteinander verrechnen, bevor ein Überlauf passiert. Und darum geht es mir.
Grüssli
-
casten
-
@Dravere schrieb:
casten
float oder double sind verboten, wenn du das meinst. Und einen grösseren Typ als 64 Bit steht mir nicht zur Verfügung.Grüssli
-
Was wäre mit (VarA * 1000 / VarB) * 1000? Ist das dann genau genug oder geht es Dir darum überhaupt keine Stellen zu verlieren?
-
Welchen Wertebereich können VarA und VarB denn jeweils annehmen? Sind das 32bit-Zahlen?
-
Kürzen, wenn möglich, und dann multiplizieren.
Ansonsten musst Du wohl auf irgendeines der "large Number" Frameworks zurückgreifen.
-
Du musst dir dia arbeit beim multiplizieren halt aufteilen. Z.B. wie in folgendem Beispiel:
1234356
=(12*100 + 34)*(3100 + 56)
=3*12*100^2 + 3*34*100 + 56*12*100 + 56*34
=36*100^2 + 774*100 + 1904
=36*100^2 + 7*100^2 + 74*100 + 19*100 + 4
=43*100^2 + 93*100 + 4Dann hast du wie in obigem Beispiel die Darstellung in Einheiten zu 1, 100 u. 100^2
Nehmen wir an, Du willst das ganze durch 758 teilen, dann nimmst Du z.B. folgenden Algorithmus:Merker = 0;
43*100^2 + 93*100 + 4 - 758
=43*100^2 + 93*100 + 4 - 8100 + 42
=43*100^2 + 85*100 + 46
Merker = 1;
43*100^2 + 85*100 + 46 - 758
=43*100^2 + 85*100 + 46 - 8100 + 42
=43*100^2 + 77*100 + 88
Merker = 2;
43*100^2 + 77*100 + 88 - 758
=43*100^2 + 77*100 + 88 - 7*100 - 58
=43*100^2 + 70*100 + 30
Merker = 3;
Die wiederholst Du bis Du keine vollen 758 mehr abziehen kannst. Der Merker ist dann dein (ganzzahliges) Divisionsergebnis.Du musst das Beispiel nur noch in einen allgemeingültigen Algorithmus umformulieren.
Das ist vielleicht nicht der schnellste Algorithmus, erfüllt aber Deine beiden Bedingungen ohne Überlauf bzw. Genauigkeitsverlust.
-
Ich hab es aufgegeben und anders gelöst. Ich sah keine andere Möglichkeit wie "MrBesserwisser" und das war mir zu langsam und umständlich.
Meine neue Lösung besteht aus BCB kodierten Zahlen, dadurch habe ich keinen oberen Grenzwert und muss keine Angst vor dem Überlauf haben. Die Multiplikation mit 1000000 geht im übrigen äusserst schnell und der Rest braucht halt ein wenig mehr oder gleich viel Zeit. Es braucht zwar definitiv mehr Speicher, aber das ist egal.
Danke für die Hilfe!
Grüssli