Increment the last digit of a number - vb.net

VB2010 I have a user form where the user inputs a number format. The routine then cycles through a list of number pairs and displays them in a list of categories:
User format "0.00"
0.00 - 164.04
164.04 - 410.10
410.10 - 820.21
What I am trying to do is to increment the first value by one digit so there is no overlap. something like:
0.00 - 164.04
164.05 - 410.10
410.11 - 820.21
I am trying to make it so it works with any number format the user inputs like "0.000" or "0.0". What I currently have is (example for value 164.04)
1. Convert the value to a string "164.04"
2. Take the right most character "4" and convert to an integer 4
3. Increment the integer value by 1 to get 5
4. Take the characters in the string from step #1 except the last and then append
the integer from Step #3 as a string to get "164.05".
Seemed to work in my VB6 program but wanted to see if anyone had any better ideas. I also don't think i accounted for the last digit being a 9.
Update: based on the suggestions below what ended up working for positive and negative numbers and integers and floats was the following:
Dim p As Integer
Dim numAsStr As String = num.ToString(fmt)
If numAsStr.IndexOf(".") = -1 Then
p = 0
Else
p = numAsStr.Length - numAsStr.IndexOf(".") - 1
End If
Dim result as Double = ((num* (10 ^ p) + 1.0) / (10 ^ p))

Here is the algorithm:
1.Find decimal points (p)
2.multiply the number by 10^p, increase it by one, divide it back by 10^p
Dim numAsStr As String = num.ToString()
Dim p As Integer = numAsStr.Length - numAsStr.IndexOf(".") - 1
Dim numInt as Integer = 10^p * num
Dim result as Double = ((10^p *num + 1.0) / 10^p).ToString()

Use "ON ERROR RESUME NEXT" construct for this problem.

Related

Convert integer value to fractional value (decimal)

Looking for a way to convert a positive number (integer) from e.g. 123 to 0.123 without using strings. Can be any size integer. Not concerned about negative values.
Dim value As Integer = 123
Dim num As Decimal = "." & value.ToString
It seems simple but I'm not sure how to do it using math. How can I convert without using strings?
You can get the number of digits using Log10. I think the best way is thusly:
Dim value = 123 'Or whatever other value
Dim digitCount = Math.Floor(Math.Log10(Math.Abs(value))) + 1
Dim result = value * CDec(10 ^ (-digitCount))
You need to use Floor rather than Ceiling in order to get the right result for 0, 10, 100, etc.
Here's one method:
Dim value As Integer = 123
Dim num As Decimal = value
While Math.Abs(num) >= 1
num = num / 10
End While
The Math.Abs takes care of negatives, so you could remove it as you say you're not concerned with them.
This also works:
Dim value as Integer = 123
Dim num as Decimal = value
num /= 10 ^ Math.Ceiling(Math.Log10(value))
It's a little harder to see what's going on initially, but it basically finds the next power of 10 that is above the number, and divides by the 10^(that power)
Edit As per Craigs answer Math.Floor then add one works better than Math.Ceiling thus:
Dim value as Integer = 123
Dim num as Decimal = value
num /= 10 ^ (Math.Floor(Math.Log10(value)) + 1)
Edit
I just did a quick performance comparison, and on my PC doing the While loop took 851ms, and the Log10 method took 158ms. That's for 1,000,000 iterations of each.

Format number in datagridview- If integer then F0, if decimal then F

I need to format all numbers in a datagridview.
If the number is a whole number then do not show the decimal point and if the number has a fraction then do show the decimal point.
I have achieved this by looping through each column and checking if the content is a double/single/decimal and then looping through each row in those columns to check each value whether the number is whole or has a fraction.
But this takes a long time for the application to process since i might have 2000 rows or more with 5 or more columns being double/single/decimal.
I can't find a standard format which does this.
Can anybody help?
dgv.SuspendLayout()
For i = 0 To dgv.Columns.Count - 1
If dgv.Columns(i).ValueType = GetType(Double) Or dgv.Columns(i).ValueType = GetType(Single) Or dgv.Columns(i).ValueType = GetType(Decimal) Then
'check If the number has a fraction
For u = 0 To dgv.Rows.Count - 1
If Not IsDBNull(dgv.Rows(u).Cells(i).Value) Then
If dgv.Rows(u).Cells(i).Value Mod 1 <> 0 Then
'number has a fraction
dgv.Rows(u).Cells(i).Style.Format = "F"
Else
'number is an integer
dgv.Rows(u).Cells(i).Style.Format = "F0"
End If
End If
Next
End If
Next
dgv.ResumeLayout()
Using the Datagridview.CellFormatting event seemed to solve the issue - Thanks Jimi. I just can't understand the difference between using the event and setting the format in a loop after populating the datagridview

How to divide line of text that has both text and numbers with $ sign in front of it?

I want to divide this array of texts into 3 divisions
SAMPLE TEXT:
Personal injury during holiday $10,000
Property damage $100,000
Car damage $10,000 for third party
Property damage $100,000 for properties located in the City area
$20,000 each and every policy
And it should be organized like this:
Division 1 - full text before numbers
Division 2 - Numbers, it always starts with $
Division 3 - full text after numbers
Note:
The number of words before and after the number is inconsistent. Only the $ sign is consistent.
You can use this, The code might look complex but by studying it you will understand it
Dim test As String = "your string here"
'Split the text into lines and store in array
Dim split1() As String = Split(test, vbLf)
Dim split2() As String
Dim split3() As String
For x As Integer = 0 To Ubound(split1) - 1
split2 = Split(split1(x))
For y As Integer = 0 To Ubound(split2) - 1
If split2(y).StartsWith("$") Then
For z As Integer = 0 To y - 1
split3(0) &= split2(z)
Next
split3(1) = split2(y)
If y < Ubound(split2) - 1 Then
For a As Integer = y + 1 To Ubound(split2) - 1
split3(2) &= split2(y)
Next
End If
End If
For b As Integer = 0 To 2
Console.WriteLine(split3(x))
' or you could use Textbox.Text += split3(x)
' Do whatever you want with those values here
'split3(0) = Text before $ sign
'split3(1) = Text with $ sign
'split3(2) = Text after $ sign
Next
Next
Next
Regex is ideal for this. I will show an example for one line but you can apply it to every line in a loop.
Dim str = "Car damage $10,000 for third party"
'Create regex which matches three groups:
'Group 1: (.*) ==> matches any characters
'Group 2: (\$[\d,]+) ==> matches $ followed by one or more digits and/or comma (,)
'Group 3: (.*) ==> matches any characters
Dim regex = New Regex("(.*)(\$[\d,]+)(.*)")
Dim match = regex.Match(str)
'Get values for all groups, skipping the first one which matches the whole string.
Dim parts = match.Groups.Cast(Of Group).Skip(1).Select(Function(g) g.Value).ToArray()
You get this array as a result:

Get the least of a series of numbers WITHOUT an array (VB.NET)

Yes, this is part of a homework assignment. And that's the trouble - I know I could use an array, but we haven't reached that part of the class yet, so I'm not supposed to use that yet. The user inputs five numbers (Doubles, using InputBoxes) and the program should drop the lowest value and calculate the average of the remaining four. At this present juncture, we've been studying For...Next loops, and this is the corresponding For...Next section in the book, so I know I'm supposed to incorporate one in here somewhere, but I have yet to figure out how to calculate and then keep a running "lowest" variable.
Thanks for the help!
Original:
Sub getAverage()
Dim first As Double = CDbl(InputBox("Enter the first grade.", "First"))
Dim second As Double = CDbl(InputBox("Enter the second grade.", "Second"))
Dim third As Double = CDbl(InputBox("Enter the third grade.", "Third"))
Dim fourth As Double = CDbl(InputBox("Enter the fourth grade.", "Fourth"))
Dim fifth As Double = CDbl(InputBox("Enter the fifth grade.", "Fifth"))
Dim min As Double = 0
Dim sum As Double = 0
For count As Integer = 1 To 5
Next
Dim average As Double = 0
txtOutput.Text = average.ToString("N2")
End Sub
Edit 1 (Thanks Guffa): What should I compare the current grade to?
Sub getAverage()
Dim min As Double = 0
Dim sum As Double = 0
For count As Integer = 1 To 5
Dim grade As Double = InputBox("Enter Grade #" & count)
sum += grade
If grade < '??? Then
min = grade
End If
Next
Dim average As Double = 0
txtOutput.Text = average.ToString("N2")
End Sub
Don't have five input statements, put one input statement in the loop instead.
You would need to keep track of:
- The sum of all values
- The lowest value that you encounter
Just add each numbers to the sum as they are entered, and update the lowest value if the entered value is lower than what you have got before.
When the user has entered all the numbers, you just subtract the lowest number from the sum of all the values, that gives you the same value as if you had added up all the numbers except the lowest one.
The average is just the sum divided by the number of values.

Best way to get the first digit from an integer of varying length in VB.NET

I am a newbie to programming and need some help with the basics.
I have a function which takes in an integer value. I want to be able to grab the first digit (or the first and second digits in some cases) of this integer and do something with it.
What is the best way in VB.NET to get the first digit of an integer (or the first and second)?
firstDigit = number.ToString().Substring(0,1)
firstTwoDigits = number.ToString().Substring(0,2);
int.Parse(firstDigit)
int.Parse(firstTwoDigits)
and so forth
I'm not well versed in VB syntax, so forgive me for the syntax errors:
dim i as integer
while i >= 10
i = i \ 10
end while
msgbox "i = " & i
Note, this prints the "first from the left" digit. Like, for "12345" it would print "1".
If you need the digits starting from the end of the integer, just get the modulu result for the tens or the hundreds, according to how many digits you need.
Dim n As Integer
n Mod 10
for the first digit, or:
n Mod 100
for the second and first digits.
If you need the first and second digits from the beginning of the number, there is another answer here which will probably help you.
for first digit you can use:
Dim number As Integer = 234734
Dim first = number.ToString.ToCharArray()(0)
for second digit you can use:
Dim number As Integer = 234734
Dim second = number.ToString.ToCharArray()(1)
This would work. You can use Math.ABS, absolute value, to eliminate negative. The number from left could be replaced by a function if you are using logic, like the overall length of the number, to determine how many of the leading characters you are going to use.
Dim number As Integer = -107
Dim result As String
Dim numberFromLeft As Integer = 2
result = Math.Abs(number).ToString.Substring(0, numberFromLeft)
This results in 10 it is a string but converting it back to a number is easy if you need to. If you need to keep track if it was positive or negative you could use the original value to apply that back to you parsed string.