Mod mit Doppel

Mache ich etwas falsch oder funktioniert der VBA-Mod-operator eigentlich nicht mit floating-point-Werte wie Verdoppelt?

So habe ich immer irgendwie davon ausgegangen, dass die VBA-Mod-operator funktionieren würde mit Doppel-auf der Grundlage der VB-Dokumentation, aber beim Versuch, herauszufinden, warum meine Rundung Funktion funktioniert nicht, ich fand einige unerwartete Mod-Verhalten.

Hier ist mein code:

Public Function RoundUp(num As Double, Optional nearest As Double = 1)
    RoundUp = ((num \ nearest) - ((num Mod nearest) > 0)) * nearest
End Function

RoundUp(12.34) zurück 12 statt 13 also grub ich ein wenig tiefer und fand, dass:

12.5 Mod 1 zurück 0 mit der return-Typ der Lange, in der Erwägung, dass hatte ich erwartet, 0.5 Typs Double.


Abschluss

Als @ckuhn203 weist in seiner Antwort, gemäß VBA-Spezifikation,

Den modulo oder Rest-operator dividiert Zahl1 durch Zahl2
(Rundung von Gleitkommazahlen in Ganzzahlen) und gibt nur die
Rest als Ergebnis.

Und

Normalerweise ist der Datentyp von Ergebnis ist ein Byte, Byte-Variante, Integer,
Integer-Variante, Lang, oder die Variante mit einem Langen, unabhängig von
ob oder nicht, Ergebnis ist eine ganze Zahl. Eine gebrochene Teil ist
abgeschnitten.

Für meine Zwecke, ich brauche eine floating-point-modulo und so habe ich beschlossen, die folgenden:

Public Function FMod(a As Double, b As Double) As Double
    FMod = a - Fix(a / b) * b

    'http://en.wikipedia.org/wiki/Machine_epsilon
    'Unfortunately, this function can only be accurate when `a /b` is outside [-2.22E-16,+2.22E-16]
    'Without this correction, FMod(.66, .06) = 5.55111512312578E-17 when it should be 0
    If FMod >= -2 ^ -52 And FMod <= 2 ^ -52 Then '+/- 2.22E-16
        FMod = 0
    End If
End Function

Hier sind einige Beispiele:

FMod(12.5, 1) = 0.5
FMod(5.3, 2) = 1.3
FMod(18.5, 4.2) = 1.7

Mich Rundung Funktion löst mein besonderes Problem ist.

  • Finden Sie die akzeptierte Antwort hier, die Ihnen helfen könnten. VBA-mod-operator akzeptiert nur lang/integer. Die akzeptierten Antworten auf die anderen F zeigt die Formel verwendet intern für MOD. Vielleicht können Sie es anpassen.
  • Danke! Ich hatte gesehen, dass die Frage in meiner sucht, aber ignoriert es, weil die Erwähnung einer "runtime error" - jetzt sehe ich, dass Sie tatsächlich-Adresse der Tatsache, dass die Mod macht Longs 😛
  • gute Frage, ähm vielleicht ist es, weil double in VBA ist eigentlich eine floating-Nummer daher die Trennung der floating-Nummer wäre nicht wirklich gute Ergebnisse erzielen, wenn multipliziert mit X tausenden.
  • Andere Vorschläge für eine genauere round-to-nearest-Formel? Für die Größenordnung der zahlen, die ich arbeite, 52 bits ist viel, aber ich würde lieben, um es allgemeiner. Ich glaube, ich könnte machen eine BigNum-Klasse, die Läden (fast) unendliche Genauigkeit von zahlen als text, aber es schien zu viel für das, was ich versuche zu erreichen. Ich habe einmal versucht zu verwenden CopyMemory trick eine Variante zu denken, es war ein Decimal... aber VBA gesagt, nope, nope, nope.
  • Ich sehe, hm lass mich nachdenken. Ich weiß, in 64bit, die Sie verwenden können, LongLong usw. so einen BIGNUM-Klasse ist nicht unbedingt eine gute Lösung. Vielleicht versucht die native C# wie float.ininity in einer COm-dll wrapper..
InformationsquelleAutor Blackhawk | 2014-05-08
Schreibe einen Kommentar