This question already has answers here:
Rounding a number down in Visual Basic
(5 answers)
Closed 6 months ago.
Can anyone give me some help on how to round half down in Visual Basic? I need 1.235 to be converted to 1.23 and NOT 1.24.
What is in the comments,
Const numD As Integer = 100 'for 3 digits 1000, etc.
Dim d As Double = 1.235#
Dim d1 As Double
d1 = Math.Round(d, 2)
Stop
d1 = Math.Round(d, 2, MidpointRounding.AwayFromZero)
Stop
d1 = Math.Round(d, 2, MidpointRounding.ToEven)
Stop
d1 = Math.Sign(d) * Math.Floor(Math.Abs(d) * numD) / numD 'winner winner
Stop
Dim value As double = 1.235
value = Math.Floor(value * 100) / 100
Related
In the following project euler program #56, Considering natural numbers of the form, a^b, where a, b < 100, what is the maximum digital sum?
so I wrote the following code:
Dim num As System.Numerics.BigInteger
Dim s As String
Dim sum As Integer
Dim record As Integer
For a = 2 To 99
For b = 1 To 99
num = a ^ b
s = num.ToString
For i = 0 To s.Length - 1
sum += CInt(s.Substring(i, 1))
Next
sum = 0
Next
Next
The answer I got from the program was not the correct answer, so I wrote the following code so I can see what numbers set a new high value and see if something is wrong.
If sum > record Then
record = sum
Console.WriteLine(a & "," & b)
End If
One of the answers was a=10 b= 81. Obviously that doesn't make sense, because that value is 1 + 81 "0" = 1, but watching the result of 10^81, was 999999999999999921281879895665782741935503249059183851809998224123064148429897728
I searched about the accuracy of BigInteger but couldn't find anything, is there something that I'm missing?
' total service till retirement
retirement = Me.DateTimePicker2.Value
appointment = Me.DateTimePicker1.Value
Dim workingTime As TimeSpan = retirement - appointment
Dim yearVal As Double = workingTime.TotalDays / 365
Dim years = CInt(Math.Floor(yearVal))
Dim monthVal = (workingTime.TotalDays - years * 365) / 30
Dim months As Int32 = CInt(Math.Floor(monthVal))
Dim dayVal = workingTime.TotalDays - (years * 365 + months * 30)
Dim days As Int32 = CInt(Math.Floor(dayVal))
Dim result = $" {years} years {months} months & {days} Days"
tservice.Clear()
tservice.Text = result
' Pay reckonable for pension.
reckonable = Val(lastpay.Text) + Val(increment.Text)
'17. Service on the date of retirement. rounded off
If months > 5 Then
totalyear = (Val(years) + 1)
End If
'1. PENSION:-17760x26x7/300=Rs. 10774.40
tpension.Clear()
pension = (Val(reckonable) * Val(totalyear) * 7 / 300)
tpension.Text = pension
i need that answer should not be zero but due to totalyear a integer variable inside if statement gives zero i want it to add a value 1 if num of months is greater than 5 kindly help me.
My code below fails to change WALRT.
dim WALRT as datetime = latest_weight_average_request_time
dim days_latest_weight_factor = 0.5
dim WALRT_new_hour = WALRT.hour * ( 1 - days_latest_weight_factor) + last_request_time.hour * days_latest_weight_factor
WALRT.AddHours( WALRT_new_hour - WALRT.hour )
WALRT.AddHours( 4 )
AddHours returns a new DateTime with the added hours.
It doesn't work modifying directly the variable provided
WALRT = WALRT.AddHours(WALRT_new_hour - WALRT.hour).AddHours(4)
However your code it is pretty weird because you are simply adding 4 hours to the initial value and all the lines in the middle can be removed.
For example, suppose the value of the Hour property of latest_weight_average_request_time is 10.
Your code assigns the same value to WALRT so the line that calculates the value of WALRT_new_hour is like this
dim WALRT_new_hour = 10 * ( 1 - 0.5) + 10 * 0.5 ' => equals to 10
and the following line (after fixing it) is
WALRT = WALRT.AddHours(10 - 10) ' ??
so the final line just add 4 hours to the initial value
WALRT = WALRT.AddHours(4)
DateTime.AddHoursreturns an new DateTime object. So you need to write e.g.
WALRT = WALRT.AddHours(4)
I'm running the following program, and get an overflow error at the first iteration once the program gets to a. From my understanding this shouldn't happen because I'm using Doubles which have a ridiculous amount of capacity, and a Long, but because it's only going up to 100 currently it shouldn't matter, and the code fails long before then. Here is my original inputs:
h0 = 1000, v0 = 0, a0 = g = -9.80665, dt = .01, m = 752.2528, b = .287875
and here's the code:
Sub drag()
Dim h0 As Double
Dim v0 As Double
Dim a0 As Double
Dim dt As Double
Dim m As Double
Dim b As Double
Dim g As Double
Dim i As Long
Dim h As Double
Dim v As Double
Dim a As Double
h0 = Worksheets("Drag").Cells(2, 8).Value
v0 = Worksheets("Drag").Cells(2, 9).Value
a0 = Worksheets("Drag").Cells(2, 10).Value
g = Worksheets("Drag").Cells(2, 10).Value
dt = Worksheets("Drag").Cells(2, 7).Value
m = Worksheets("Drag").Cells(2, 4).Value
b = Worksheets("Drag").Cells(2, 5).Value
Debug.Print h0 & v0 & a0 & dt & m & b
For i = 1 To 100
v = v0 + a0 * dt
h = 0.5 * a0 * (dt ^ 2) + v0 * dt + h0
a = m * g - b * (v ^ 2) 'Line where overflow occurs
v0 = v
h0 = h
a0 = a
Cells(i + 2, 8) = h0
Cells(i + 2, 9) = v0
Cells(i + 2, 10) = a0
Next i
Debug.Print h0 & v0 & a0 & dt & m & b
End Sub
Hope this is an easy fix.
Your overflow happens when i=14 (14th pass through the loop) and when v = -1.689 x 10^209. I don't know what you are trying to do, but v is blowing up. It would help if you describe what you are trying to do. – John Coleman 17 mins ago
#John Coleman I see the problem now, I'm doing the drag equation and I forgot to divide the a term by m, thanks. – Anthrochange 9 mins ago
You have already identified what needs to be done.
Now for the explanation on why the overflow on m * g - b * (v ^ 2). I added a watch as shown below
Consider the before and after screenshot
Before v = v0 + a0 * dt is calculated
After v = v0 + a0 * dt is calculated
What you see here is a very peculiar behaviour. A Type Double changing to an Integer
This is not normal and has been experienced before. Unfortunately this problem exists in Excel for a long time and unfortunately is also present in Excel 2016. It occurs only when you are using very large numbers. These kind of bugs are very rare, but yes, they do exist.
One can have a similar kind of experience when using MOD as mentioned in the below link
The MOD Function
The variable in question that is getting an overflow is v. You defined it as a double, which means you can only put numbers in the range of 1.79769313486232 * 10^308 to 4.94065645841247 * 10^–324. VBA uses 8 bytes to hold the double data. Any number outside of this huge range causes an overflow. (see here for more information about DBA data types)
How big of a number are you expecting? A rough estimate fo the number of atoms in the universe is 1 * 10^82, and the double value range goes to almost 2 *10^308. If you need to work with numbers that large, you're going to have to use a different method because it simply won't fit in the standard VBA data types.
After run the program I show value of Power1 is zero, why?
Here codes;
Dim Guc1....Guc59 as decimal
Guc1=Val(TextBox5.Text)*Val(Textbox98.Text)
.
.
.
Guc59=Val(TextBox42.Text)*Val(Textbox12.Text)
For i = 1 To 59 Step 2
Dim txt As TextBox = CType(TabControlPanel1.Controls("TextBoxX" & i), TextBox)
Dim guc As Decimal = CType(("Guc".ToString & i), Decimal)
Hız1 = Val(txt.Text) * RollinRadius * 3.14 * 3.6 / (Val(TextBox1.Text) * Val(TextBox33.Text) * 30)
Power1 = guc * 3.14 / (30 * 1000) *2 *3)
ListBox2.Items.Add(Power1)
Next
Power1 is zero because guc will currently always be zero. You cannot access variables by their names like you're trying to do. "Guc" & i will just result in a normal string, which it cannot convert since Guc is not numerical. The only way to access variables dynamically by their name is to use Reflection.
But the best way to do what you're trying to achieve is to use a List(Of T) or an Array:
Dim Guc As Decimal = New Decimal(59 - 1) {} '59 - 1 = 59 items.
...
Dim gucx As Decimal = Guc(i - 1)
...
Power1 = gucx * 3.14 / (30 * 1000) * 2 * 3