Игнорировать ошибку переполнения, когда результат умножения больше, чем может содержать двойное число - PullRequest
1 голос
/ 12 апреля 2011

Во время некоторой итеративной оптимизации следующий код VBA для вычисления двумерного нормального CDF иногда выдает ошибку переполнения в строке с z = hx * hy * c внутри цикла while верхней функции.

Iотлаживается код, и переполнение происходит, когда умножаемые числа приводят к числу, превышающему число, которое может содержать двойное число.

Можете ли вы показать мне, как справиться с проблемой, игнорируя итерации цикла с такими высокими значениями- Думаю, это единственно возможное решение (?).Я пробовал себя со строкой следующей итерации On Error Goto перед умножением и помещал точку перехода следующей итерации перед Wend, но ошибка сохраняется.

Function tetrachoric(x As Double, y As Double, rho As Double) As Double
    Const FACCURACY As Double = 0.0000000000001
    Const MinStopK As Integer = 20
    Dim k As Integer
    Dim c As Double
    Dim z As Double
    Dim s As Double
    Dim hx As Double
    Dim hx1 As Double
    Dim hx2 As Double
    Dim hy As Double
    Dim hy1 As Double
    Dim hy2 As Double
    Dim CheckPass As Integer

    hx = 1
    hy = 1
    hx1 = 0
    hy1 = 0
    k = 0

    c = rho
    z = c
    s = z
    CheckPass = 0

    While CheckPass < MinStopK
        k = k + 1
        hx2 = hx1
        hy2 = hy1
        hx1 = hx
        hy1 = hy
        hx = x * hx1 - (k - 1) * hx2
        hy = y * hy1 - (k - 1) * hy2
        c = c * rho / (k + 1)
        z = hx * hy * c
        s = s + z
        If Abs(z / s) < FACCURACY Then
            CheckPass = CheckPass + 1
        Else
            CheckPass = 0
        End If
    Wend
    tetrachoric = s
End Function


Public Function bivnor(x As Double, y As Double, rho As Double) As Double
'
' bivnor function
' Calculates bivariat normal CDF F(x,y,rho) for a pair of standard normal
' random variables with correlation RHO
'
If rho = 0 Then
    bivnor = Application.WorksheetFunction.NormSDist(x) * _
         Application.WorksheetFunction.NormSDist(y)
Else
    bivnor = Application.WorksheetFunction.NormSDist(x) * _
         Application.WorksheetFunction.NormSDist(y) + _
         Application.WorksheetFunction.NormDist(x, 0, 1, False) * _
         Application.WorksheetFunction.NormDist(y, 0, 1, False) * _
         tetrachoric(x, y, rho)
End If
End Function

Источник: Доступно для загрузки по http://michael.marginalq.com/

Ответы [ 3 ]

2 голосов
/ 13 апреля 2011

вы выходите за пределы компьютерной архитектуры. Многие сложные алгоритмы не могут быть реализованы 1: 1 с их математическим представлением из-за соображений производительности и / или ошибочного поведения при переполнении. Об этих проблемах есть исключительно хороший блог - Джон Д. Кук .

Пожалуйста, посмотрите здесь для лучшей реализации.

Вы также можете попробовать связать внешнюю библиотеку, которая дает вам произвольную точность обработки чисел, конечно, реализованную с использованием очень дорогих (с точки зрения времени процессора) программных алгоритмов. Больше можно найти здесь .

1 голос
/ 14 апреля 2011

http://www.codeproject.com/KB/recipes/float_point.aspx описывает, как использовать логарифмы, чтобы избежать переполнения и переполнения, что является простым, но довольно эффективным способом решения проблем переполнения.На самом деле, это так просто, но логично, почему мы сами не подумали об этом решении?;)

1 голос
/ 12 апреля 2011

Обновлен код с использованием On Error Resume Next вместо On Error Goto:

While CheckPass < MinStopK
    k = k + 1
    hx2 = hx1
    hy2 = hy1
    hx1 = hx
    hy1 = hy
    hx = x * hx1 - (k - 1) * hx2
    hy = y * hy1 - (k - 1) * hy2
    c = c * rho / (k + 1)
    On Error Resume Next
    z = hx * hy * c
    If Err.Number = 0 Then
        s = s + z
        If Abs(z / s) < FACCURACY Then
            CheckPass = CheckPass + 1
        Else
            CheckPass = 0
        End If
    Else
        Err.Clear
    End If
Wend
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...