2016-04-25 4 views
2

Сотрудник шахт разработал что-то на Java, что делает некоторые простые вычисления на Java. Я конвертирую код в VBA, но я понял, что, как только вычисления приведут к 11 цифрам или более, вычисления не синхронизированы.Как имитировать переполнение Int32?

Java код

int prime = 31; 
int result = 1; 
String test = "Periwinkle" 

for (char c : test.toCharArray()) { 
result = prime * result + Character.getNumericValue(c); 
System.out.println("letter " + c + " number " + Character.getNumericValue(c)); 
System.out.println(result + " from " + c); 
} 
System.out.println(Math.abs(result)); 

VBA Code

Dim arr As Variant 
Dim letr As String 
Dim num As Integer 
Dim result, prime As Integer 

For Each cell In Range("A1") 'A1 = Periwinkle 
    result = 1 
    prime = 31 
    arr = CharacterArray(cell.value) 
For Each element In arr 
    letr = element 
    'Debug.Print "Letter: " & letr 
    num = getNumber(letr) 
    'Debug.Print "Number: " & num 
    result = prime * result + num 
    'Debug.Print "Result: " & result 
    Cells(cell.Row, 3).value = Math.Abs(result) 
Next 
Next 

Все расчеты в синхронизации до буквы "п", в котором вычисление в Java приводит к "-1413090664" в то время как в результатах VBA в «50126516888». Проблема в том, что в Java с result определяется как int, он не может содержать до 11 цифр, что приводит к отрицательному числу.

Примечание: Я знаю, что я могу изменить код Java, чтобы использовать double, но я не могу внести это изменение. Я ищу обходное решение в VB.

Мне нужно как можно больше имитировать код Java, поэтому мне нужен код VBA для имитации непроверенного переполнения Int32. Как это может быть сделано?

+0

Использовать двойной? Я не понимаю вашу проблему. – redFIVE

+0

Является ли целочисленное переполнение на стороне java действительно предназначенным поведением? Кажется, что java-сторона должна быть изменена, это правильно? –

+0

@redFIVE, я бы хотел использовать двойной, но по сути код Java установлен в камне. Я не могу вносить в него изменения. Эти коды по существу генерируют числа sku, которые мы не можем изменить. – NuWin

ответ

1

Невозможно отключить проверку переполнения, но вы можете избежать этого, работая с двумя int32. Эта функция VBA поможет вам точно такой же результат:

Sub Usage() 
    Debug.Print Hash("Periwinkle") 
End Sub 

Public Function Hash(text As String) As Long 
    Dim lo&, hi&, i% 
    lo = 1 
    For i = 1 To Len(text) 
    lo = 31& * (lo And 65535) + GetNumericValue(AscW(Mid$(text, i, 1))) 
    hi = 31& * (hi And 65535) + (lo \ 65536) 
    Next 
    Hash = Abs((lo And 65535) + (hi And 32767) * 65536 + (&H80000000 And -(hi And 32768))) 
End Function 

Private Function GetNumericValue(ByVal c As Integer) As Integer 
    Select Case c 
    Case 48 To 57: GetNumericValue = c - 48 '[0-9]' 
    Case 65 To 90: GetNumericValue = c - 55 '[A-Z]' 
    Case 97 To 122: GetNumericValue = c - 87 '[a-z]' 
    Case 188 To 190: GetNumericValue = -2 
    Case 178:  GetNumericValue = 2 
    Case 179:  GetNumericValue = 3 
    Case 185:  GetNumericValue = 1 
    Case Else:  GetNumericValue = -1 
    End Select 
End Function 

Обратите внимание, что код Java является вычислением хэша, полученным из алгоритма FNV.

+0

Сэр, вы гений. Если бы я мог утроить это, я бы это сделал. – NuWin