![]() |
Aufrunden einer Zahl auf nächstes Vielfaches
Hallo DPler! :hi:
Ich stehe im Moment leider mathematisch etwas auf dem Schlauch. Ziel ist es, eine ganze Zahl auf das nächste Vielfache von m aufzurunden. Hier unterscheidet sich die Aufgabe in zwei Situationen: (1) m ist bereits beim Programmieren bekannt und entspricht einer Zweierpotenz, in meinem Fall 2^12, also 4096. (2) m ist eine beliebige, unbekanntem ganze Zahl Hier ein kleiner Demonstrations-Code, der in beiden Fällen tut was er soll, allerdings sehr unschön.
Code:
Ich würde mich freuen, wenn ihr mir helfen könntet, die Zahl korrekt aufzurunden. Für die zwei unterschiedlichen Fälle sind auch zwei unterschiedliche Vorgänge in Ordnung, es interessiert mich hier lediglich, wie man in beiden Fällen am besten Vorgehen kann. Bei (1) lässt sich möglicherweise besser mit Bitschupserei arbeiten.
while zahl % m != 0:
zahl = zahl + 1 Das Ganze muss unabhängig von jeder Sprache und Bibliothek funktionieren, also kein ceil() o.ä. ;-) Vielen Dank für eure Hilfe! :) Liebe Grüße, Valentin |
AW: Aufrunden einer Zahl auf nächstes Vielfaches
Zitat:
Für den allgemeinen Fall: Die Signumsfunktion kann man sich Bit-Arithmetisch bauen (siehe z.B.: ![]()
Code:
x = Zahl
m = Vielfaches, auf das x gerundet werden soll f = x div m (oder darf man auch keine Integer-Division voraussetzen? Kann man aber zur Not ja mit Modulo bauen...) fa = sgn(x mod m) result = (f + fa) * m |
AW: Aufrunden einer Zahl auf nächstes Vielfaches
Auf 2^12 aufrunden (mit Bitschubserei):
Code:
Mit der von Melfin genannten Signum-Funktion würde es so gehen:
BIT12 = 1 << 12
MASK11 = BIT12 - 1; // Bitmaske unterste 11 Bits if (MASK11 & eingabe != 0) { ergebnis = (eingabe & ~MASK11) + BIT12; } else { ergebnis = eingabe; }
Code:
Das geht beides allerdings nur mit positiven Zahlen gut.
BIT12 = 1 << 12
MASK11 = BIT12 - 1; ergebnis = (eingabe & ~MASK11) + (sgn(eingabe & ~MASK11)) << 12; EDIT: Das musste jetzt einfach sein :mrgreen:
Delphi-Quellcode:
{$ASMMODE intel}
function roundUp4096(x: longword): longword; pascal; const mask11: longword = (1 shl 12) - 1; not_mask11: longword = not ((1 shl 12) - 1); begin asm mov edx, eax // eax = edx = x and eax, not_mask11 xor ecx, ecx // clear ecx and edx, mask11 setnz cl // cl = 1 if not zeroflag else 0 shl ecx, 12 add eax, ecx end; end; |
AW: Aufrunden einer Zahl auf nächstes Vielfaches
@valle
... also Dein
Delphi-Quellcode:
ist äquivalent zu
while zahl % m != 0:
zahl = zahl + 1
Delphi-Quellcode:
oder hab ich was falsch verstanden ?
zahl, m: integer;
zahl := ((zahl + m-1) div m ) * m; Wenn es zeitkritisch ist kann man daran noch einiges optimieren |
AW: Aufrunden einer Zahl auf nächstes Vielfaches
Hallo,
vielen Dank für eure Antworten! :) Jetzt wenn man weiß wie's geht, ist die Sache doch eigentlich ganz einfach. ;-) @Meflin: Die Sache muss unabhängig sein, da der Code Teil eines Betriebssystem-Kernels ist. Liebe Grüße, Valentin |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz