Having a problem with this code.
my coding is the following:
fitvalchild1 = 0
fitvalchild2 = 0
For i = 1 To 30
counter = 30
Do While counter > 0
fitvalchild1 = fitvalchild1 + child1(counter) * 2 ^ (i - 1)
fitvalchild2 = fitvalchild2 + child2(counter) * 2 ^ (i - 1)
counter = counter - 1
Loop
Next i
all the variables are declared as long...
Still i get the Error : overflow and the line highlighted is:
fitvalchild1 = fitvalchild1 + child1(counter) * 2 ^ (i - 1)
The Long datatype has a maximum size of 2,147,483,647.
2 ^ (30-1) = 536,870,912
so, depending on the value of child1(counter) and fitvalchild1, you'll easily exceed the maximum.
You're adding the value to itself with each loop, so after 4-5 loops, you'll likely get the error.
If you don't mind switching away from an integer type, you might try using Currency datatype. It has a maximum size of 922,337,203,685,477.5807
The range for the long data type is -2,147,483,648 to 2,147,483,647. The values in child1 and child2 don't need to very big to overflow since 2^29 is very close to the limit.
Related
I've encountered a problem with a program I'm writing for school. I need to verify credit card numbers using the Luhn Algorithm, however I'm having some difficulty in getting the logic of the algorithm to work correctly. I believe I know where the problem is, but I'm unable to fix it.
I believe the problem is here:
For i = 0 To cardInput.Text.Length - 2 Step -2
Dim x = (i * 2)
If x > 9 Then
x = x - 9
End If
oddTotal += x
Next
'Sum of undoubled digits
For i = 0 To cardLength - 1 Step -2
evenTotal += i
Next
total = oddTotal + evenTotal
checkSum = total
infoOutput.Items.Add("CheckDigit: " & checkDigit)
infoOutput.Items.Add("CheckSum :" & checkSum)
'Verify that the card is valid by the Mod 10 (Lund algoritm)
If checkSum = checkDigit Or checkSum = 0 Then
valid = True
Else
valid = False
End If
If it's needed, the rest of my project can be seen here
My code doesn't seem to start at the last digit and take every other digit back to the beginning to be doubled. Is the Step -2 operator incorrect here? What am I doing wrong?
There are several problems here. Particularly:
If you want a loop to count backwards, you have to start at the higher index and end at the lower one. So:
For i = cardInput.Text.Length - 2 To 0 Step -2
Then, instead of using i directly, you should use the i-ith digit:
Dim x = Val(cardInput.Text(i))
The same applies to your sum of evens.
If you want to check if the last digit is zero, use the Mod operator:
valid = (checkSum Mod 10 = 0)
I have a calculation like this: 3 * 12300 / 160. The result is: 230.625. But I just want the integer part, 230.
In C, this can be done using something like this: int MyVar = (int)3*12300/160;
Is there a way in VBA (With MS-Access) for force the result to be an integer?
You can round down using the Int or Fix functions.
Since you know the result you want is a whole number, you should store the result in a variable of type Long (or Integer if you're absolutely certain it will always be smaller than 32768).
Dim l As Long
l = Int(3 / 160 * 12300) ' <~~~~ Yes, I switched the numbers around on purpose!*
MsgBox "l = " & l
* Why did I switch the numbers around? Because the expression 3 * 12300 / 160 will throw an error in VBA. Read here why: Overflow when multiplying Integers and assigning to Long
I'm testing the speed of some functions so I made a test to run the functions over and over again and I stored the results in an array. I needed them to be sorted by the size of the array I randomly generated. I generate 100 elements. Merge sort to the rescue! I used this link to get me started.
The section of code I'm focusing on:
private void mergesort(int low, int high) {
// check if low is smaller then high, if not then the array is sorted
if (low < high) {
// Get the index of the element which is in the middle
int middle = low + (high - low) / 2;
// Sort the left side of the array
mergesort(low, middle);
// Sort the right side of the array
mergesort(middle + 1, high);
// Combine them both
merge(low, middle, high);
}
}
which translated to VB.NET is
private sub mergesort(low as integer, high as integer)
' check if low is smaller then high, if not then the array is sorted
if (low < high)
' Get the index of the element which is in the middle
dim middle as integer = low + (high - low) / 2
' Sort the left side of the array
mergesort(low, middle)
' Sort the right side of the array
mergesort(middle + 1, high)
' Combine them both
merge(low, middle, high)
end if
end sub
Of more importance the LOC that only matters to this question is
dim middle as integer = low + (high - low) / 2
In case you wanna see how merge sort is gonna run this baby
high low high low
100 0 10 0
50 0 6 4
25 0 5 4
12 0 12 7
6 0 10 7
3 0 8 7
2 0 :stackoverflow error:
The error comes from the fact 7 + (8 - 7) / 2 = 8. You'll see 7 and 8 get passed in to mergesort(low, middle) and then we infinite loop. Now earlier in the sort you see a comparison like this again. At 5 and 4. 4 + (5 - 4) / 2 = 4. So essentially for 5 and 4 it becomes 4 + (1) / 2 = 4.5 = 4. For 8 and 7 though it's 7 + (1) / 2 = 7.5 = 8. Remember the numbers are typecasted to an int.
Maybe I'm just using a bad implementation of it or my typecasting is wrong, but my question is: Shouldn't this be a red flag signaling something isn't right with the rounding that's occuring?
Without understanding the whole algorithm, note that VB.NET / is different than C# /. The latter has integer division by default, if you want to truncate decimal places also in VB.NET you have to use \.
Read: \ Operator
So i think that this is what you want:
Dim middle as Int32 = low + (high - low) \ 2
You are correct in your diagnosis: there's something inconsistent with the rounding that's occurring, but this is entirely expected if you know where to look.
From the VB.NET documentation on the / operator:
Divides two numbers and returns a floating-point result.
This documentation explicitly states that , if x and y are integral types, x / y returns a Double. So, 5 / 2 in VB.NET would be expected to be 2.5.
From the C# documentation on the / operator:
All numeric types have predefined division operators.
And further down the page:
When you divide two integers, the result is always an integer.
In the case of C#, if x and y are integers, x / y returns an integer (rounded down). 5 / 2 in C# is expected to return 2.
I'm having a problem with some vba code.
I have a if statement that doesn't treat the same content equally.
e.g: 0,1 equals 0,1, but a re-run 0,1 does not equal 0,1
(this values are shown by MVBA)
The code is long so before posting it i would like to know if it's possible to see the machine perspective in a if statement (hex, ascii...). This because, although the debug is telling me they are the same (through msgbox, vartype, etc), the if statement is not activated.
pseudo code:
x = 0,0000001 * 1*10^6 (which equals 0,1)
y = 0,0001 * 1*10^3 (which also equals 0,1)
if statement:
x doesn't enter
y does
end if
This is because the floating-point implementation may not be able to represent those number accurately due to the fact that they are encoded in a base 2 representation.
If you want to compare them, I would suggest using Cdec (wich converts to Decimal, a VBA custom base 10 floating-point)
Debug.Print (0.0000001 * 1 * 10 ^ 6) = (0.0001 * 1 * 10 ^ 3) ' False
Debug.Print CDec(0.0000001 * 1 * 10 ^ 6) = CDec(0.0001 * 1 * 10 ^ 3) ' True
While they both display 0.1, in fact 0.0000001 * 1 * 10 ^ 6 flaoting-point value is 0x3FB9999999999999 whereas 0.0001 * 1 * 10 ^ 3 returns 0x3FB999999999999A.
I'd recommend reading What Every Computer Scientist Should Know About Floating-Point Arithmetic
I am just trying to experience myself the use of For Loop vs. Linq statement in VB.NET. However, I've found a difference in a result of which I found interesting, but had no clue why it 's happening. (I am trying to find the sum of all the multiples of 3 or 5 below 1000.) Below are my two ways of doing that:
method 1: For loop
Dim sum1 As Integer = 0
For i As Integer = 0 To 999
If i Mod 3 = 0 Or i Mod 5 = 0 Then
sum1 += i
End If
Next
Method 2: Linq statement
Dim sum2 As Integer = Enumerable.Range(0, 999).Where(Function(x As Integer) x Mod 3 = 0 Or x Mod 5 = 0).Sum
Obviously method 2 is shorter and of more functional style. But interestingly, I found that Sum1 = 233168 and Sum2 = 232169 which is different by 1001. Can anyone please tell me why it's happening? Thank you.
For loop is inclusive, so you get 1000 numbers (0 to 999). Enumerable.Range will give you 999 numbers, because that's what you asked it for passing 999 as second parameter (0 to 998).
999 is the one that makes the difference.
Ok I've found it, my very simple mistake: Enumerable.Range(start,count) which I thought as if it were Enumerable.Range(firstNumber, lastNumber).