Арифметическая операция привела к переполнению - Vb.Net - PullRequest
0 голосов
/ 20 сентября 2018

Привет, я получаю следующую ошибку при вычислении времени по Гринвичу с использованием длинных наносекунд.

System.OverflowException : 'Арифметическая операция привела к переполнению.'

Есть ли другой тип данных, который лучше работал бы с большими значениями?

Private Sub gmtime(ByVal iSeconds As Object, ByVal iNanoseconds As Long, ByRef Timestamp As String)

    Dim time As Object
    Dim islpyr, lpcnt As Long
    Dim t As Object
    Dim i As Object
    Dim ystart As Long
    Dim y As Long
    Dim sph As Object  'seconds per hour
    Dim spd As Object  'seconds per day
    Dim spy As Object  'seconds per year
    Dim tm_sec As Long
    Dim tm_min As Long
    Dim tm_hour As Long
    Dim tm_mday As Long
    Dim tm_mon As Long
    Dim tm_year As Long
    Dim tm_wday As Long
    Dim tm_yday As Long
    Dim tm_isdst As Long
    Dim mons(11) As Long
    Dim temp As Object
    Dim iMicroSeconds As Long
    Dim iZeroCount As Long
    Dim strZero As String
    Dim strMicro As String
    Dim iMicroData As Long

    mons(0) = 31
    mons(1) = 28
    mons(2) = 31
    mons(3) = 30
    mons(4) = 31
    mons(5) = 30
    mons(6) = 31
    mons(7) = 31
    mons(8) = 30
    mons(9) = 31
    mons(10) = 30
    mons(11) = 31

    sph = CDec(60 * 60)
    spd = CDec(24 * sph)
    spy = CDec(365 * spd + 6 * sph)   'a year is about 365.25 days

    tm_isdst = 0

    time = CDec(iSeconds)
    If time < 0 Then
        time = time * (-1)
    End If
    i = CDec(time)
    i = Fix(i / spd) Mod 7 + 4
    While i >= 7
        i = i - 7
    End While
    tm_wday = i
    temp = Fix(time / spd)
    temp = temp * spd
    i = time - temp
    tm_hour = Fix(i / sph) Mod 24
    tm_min = Fix(i / 60) Mod 60
    tm_sec = i Mod 60

    y = Fix(time / spy)
    y = y + 370
    time = Fix(time / spd)

    Do
        islpyr = 0
        If ((y Mod 4) = 0) And (((y Mod 100) <> 0) Or ((y Mod 400) = 0)) Then
            islpyr = 1
        End If
        lpcnt = Fix(y / 4)
        lpcnt = lpcnt - Fix(y / 100)
        lpcnt = lpcnt + Fix(y / 400)

        lpcnt = lpcnt - 89
        ystart = (y - 370) * 365 + lpcnt
        If ystart > time Then
            y = y - 1
        End If

    Loop While ystart > time

    time = time - ystart

    If time = 365 Then
        time = 0
        y = y + 1
    End If

    If islpyr Then
        time = time + 1
    End If
    tm_yday = time
    time = time + 1

    For i = 0 To 10
        t = mons(i)
        If (i = 1) And (islpyr = 1) Then
            t = t + 1
        End If
        If time <= t Then
            Exit For
        End If
        time = time - t
    Next i

    tm_year = y - 300 + 1900
    tm_mon = i + 1
    tm_mday = time

    strZero = "."
    iZeroCount = 6
    iMicroSeconds = Fix(iNanoseconds / 1000)
    iMicroData = iMicroSeconds
    While iMicroSeconds <> 0
        iMicroSeconds = Fix(iMicroSeconds / 10)
        If (iMicroData Mod 10) = 0 Then
            iMicroData = iMicroSeconds
        End If
        If iZeroCount <> 0 Then
            iZeroCount = iZeroCount - 1
        End If
    End While

    For i = 1 To iZeroCount
        strZero = strZero + "0"
    Next i

    If Fix(iNanoseconds / 1000) <> 0 Then
        strMicro = strZero + CStr(Fix(iNanoseconds / 1000))
    Else
        strMicro = strZero
    End If

    Timestamp = CStr(tm_year) + "-" + CStr(tm_mon) + "-" + CStr(tm_mday) + " " + CStr(tm_hour) + ":" + CStr(tm_min) + ":" + CStr(tm_sec) + strMicro

End Sub

Это не позволило бы мне добавить код, поскольку сообщение в основном состоит из кода.Значения наносекунд поступают из файла формы сигнала, и эта функция используется для обработки его во время GMT.

Функция вызывается в цикле для каждой строки файла и возвращает эту ошибку в середине цикла.

Значение ' 1.5518651852110167E + 270 ' при появлении ошибки

1 Ответ

0 голосов
/ 21 сентября 2018

Извините, но нет способа поместить число 10^270 внутрь ЛЮБОЙ переменной.

Самая большая переменная для чисел - Long, которая содержит:

64-разрядные (8-байтовые) целые числа со знаком в диапазоне значений от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 (9,2 ... E + 18 ).

С Длинный тип данных

Я предлагаю вам избегать подсчета времени в наносекунд вместо использования секунд, минутили даже дни, если ваш TimeSpan слишком велик.

Подсчет времени в наносекундах не имеет смысла.

Замечания

Если вы не можете избежать использования наносекунд, потому что ваш файлв наносекундах ваш единственный вариант - преобразовать значение наносекунды в формате DateTime в каждой строке и надеяться, что это значение будет меньше 9.2E + 18

В противном случае вы можете использовать BigInteger и используйте его для вычисления DateTime для каждой строки вашего файла.

Просто для любопытства: вам понадобится 896 bytes unsigned DataType для хранения 1.5*10^270 внутри него.

...