vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Brandneu! sevEingabe v3.0 - Das Eingabecontrol der Superlative!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2018
 
zurück
Rubrik: Variablen/Strings · Algorithmen/Mathematik   |   VB-Versionen: VB2005, VB200828.05.08
MOD-Operator bei nicht-ganzzahligen Werten

Die Modulo-Division und die ganzzahlige Division korrespondieren bei Gleitkomma-Werten nicht.

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  30.611 
ohne HomepageSystem:  WinNT, Win2k, WinXP, Vista, Win7, Win8, Win10kein Beispielprojekt 

Die Modulo-Division liefert den ganzzahligen Rest nach Durchführung einer ganzzahligen Division. Eine eindeutige und allgemein gültige Definition der Modulo-Division gibt es nicht. Es hängt von der Programmiersprache ab, wie die Modulo-Division tatsächlich 'implementiert' worden ist.

Für den Zusammenhang zwischen der ganzzahligen Division und der Modulo-Division gilt aber im allgemeinen:

Divident = (Divident \ Divisor) * Divisor + ( Divident Mod Divisor )

Das Vorzeichen des Wertes, der bei der Modulo-Division als Resultat ermittelt wird, entspricht dem Vorzeichen des Dividenten (ausser bei 0).

Wenn mindestens ein Operand (Divident oder Divisor) nicht-ganzzahlig ist, wird in Net-VB auf eine Erweiterung der Modulo-Division zurückgegriffen.

Die Modulo-Division liefert in diesem Fall den (meist) nicht-ganzzahligen Rest einer 'gewöhnlichen' Gleitkomma-Division, bei der der Nachkomma-Anteil des Resultats abgeschnitten worden ist.

Als Formel dargestellt: a mod b <----> a - (b * Fix(a / b))

17 mod 3.5 = 3 
(weil 17 / 3.5 = 4,irgendwas ---> 4 * 3.5 = 14, d.h. Rest = 3)
17.5 Mod 3.5 = 0.0 
(weil 17.5 / 3.5 = 4.0)

Zum Vergleich: Die Modulo-Division (mathematisch) gerundeter Werte:

CLng(17.5) Mod CLng(3.5) = 2
(weil 18 \ 4 = 4 ---> 4 * 4 = 16, d.h. Rest = 2)

Es kann bei nicht-ganzzahligen Operanden eine Abweichung gegenüber der Modulo-Division gerundeter Werte auftreten, die sich durch eine nachträgliche Ganzzahl-Rundung des Ergebnisses NICHT beseitigen läßt.

Und noch etwas ist zu beachten: Bei nicht-ganzzahligen Werten in IEEE-Variablen, können im Ergebnis die IEEE-Sonderwerte 'Inifinity' oder 'NaN' entstehen. Bei nicht-ganzzahligen Werten in Variablen des Datentyps 'Decimal' werden - im Gegensatz dazu - bei Quotienten-Überlauf und Null-Divisoren Ausnahmen ausgelöst.

Der Variablentyp der Rückgabe des Mod-Operators entspricht den Operanden. Das kann jeder numerische Datentyp sein, z.B. auch Byte (falls 'Byte' Mod 'Byte'). Die VB-Dokumentation (2005/2008) schreibt dazu:

Als Datentyp des Ergebnisses wird der kleinste Datentyp gewählt, der alle möglichen Ergebniswerte der Division mit den Datentypen von 'number1' ( = Divident) und 'number2' ( = Divisor) speichern kann.

Es ist deshalb Vorsicht geboten, wenn man (ab VB2008; Option Infer ON) als Ergebnisvariable eine inferentiell deklarierte Variable verwendet.

Dim x = a mod b ' Der Typ von x wird durch MOD festgelegt

In VB ist die Ganzzahl-Division NICHT entsprechend der Modulo-Division erweitert worden.

Bei 'Option Strict On' kann eine Ganzzahl-Division mit Gleitkomma-Operanden nicht durchgeführt werden. Bei der ganzzahligen Division werden die Argumente nämlich zunächst in LONG-Variable transformiert. Da es sich dabei um eine 'einschränkende' Konvertierung handelt, ist sie als 'implizite' nicht erlaubt.

Erwarten würde man, dass die Ganzzahl-Division bei nicht-ganzzahligen Werten ebenfalls eine der Modulo-Division entsprechende Erweiterung aufweist.

c = a \ b <----> c = Fix( a / b )

Das nicht der Fall, sondern berechnet wird: c = CLng(a) \ CLng(b)

Die Ergebnisse der Ganzzahl-Division und der Modulo-Division nicht-ganzzahliger Operanden korrespondieren deshalb in den meisten Fällen NICHT miteinander.

Bei der Konvertierung durch 'CLng' wird das sog. ‚Banker's Rounding’ verwendet, das im deutschen Sprachraum meist als 'mathematisches Runden' bezeichnet wird ( = Runden auf die nächste gerade Ziffer: 1.5 --> 2, 2.5 --> 2 !!)

(Man darf diese Rundungs-Variante nicht verwechseln mit dem 'kaufmännischen' Runden, bei dem ab "5000..." stets aufgerundet wird (1.5 ---> 2, 2.5 ---> 3).

In VB erreicht man dieses Verhalten (bei positiven Zahlen) durch den Parameter 'MidPointRounding.AwayFromZero'. Speziell beim Runden auf ganze Zahlen ist das 'mathematische' Runden in vielen Anwendungsfällen nicht unproblematisch.)

Sind in einem Programm nicht-ganzzahlige Operanden zugelassen, kann es erforderlich sein, dass entweder für die Ganzzahl-Division (Anwendung der obigen Formel) ODER für die Modulo-Division (Rundung der Argumente auf LONG durch ein geeignetes Verfahren) eine eigene Funktion verwendet wird, damit aufeinander beziehbare Resultate entstehen.

Hinweis für VB6-Umsteiger:
Wenn Se sich jetzt wundern, liegen Sie richtig.

In VB6 ist der 'Mod'-Operator als reiner Ganzzahl-Operator implementiert, d.h. nicht-ganzzahlige Operanden werden automatisch auf 0 Digits gerundet.

Die aktuellen VB-Versionen erfordern, dass man diese Konvertierung bei der Modulo-Division ggf. explizit durchführt.

Bei der Umstellung von VB6-Programmen weist der Upgrade-Assistent auf das geänderte Verhalten des Mod-Operators hin.

Dieser Tipp wurde bereits 30.611 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2018 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel