Мод с парой

Я делаю что-то не так или оператор VBA Mod на самом деле не работает со значениями с плавающей запятой, такими как Doubles?

Поэтому я всегда предполагал, что оператор VBA Mod будет работать с Doubles на основеVB документация, но, пытаясь выяснить, почему моя функция округления не работает, я обнаружил неожиданное поведение мода.

Вот мой код:

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

RoundUp(12.34) возвращается12 вместо13 поэтому я вырыл немного глубже и обнаружил, что:

12.5 Mod 1 возвращается0 с типом возврата Long, тогда как я ожидал 0,5 с типом Double.

Заключение

Как@ ckuhn203 указывает в своем ответесогласно спецификации VBA,

Оператор модуля или остатка делит число 1 на число 2 (округляя числа с плавающей запятой до целых) и возвращает в качестве результата только остаток.

А также

Обычно типом данных результата является Байт, Байт, Вариант Целого, Вариант Целого, Длинный или Вариант, содержащий Длинный, независимо от того, является ли результат целым числом или нет. Любая дробная часть усекается.

Для моих целей мне нужен модуль с плавающей запятой, и поэтому я решил использовать следующее:

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

Вот некоторые примеры:

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

Использование этого в моей функции округления решает мою конкретную проблему.

Ответы на вопрос(2)

Ваш ответ на вопрос