Reputation: 351
This is more of a math/logic question so I apologize if this isn't the proper place to ask this question, I've just been working at this for hours and can't seem to find the right solution. I have a have a field in a database that I'm using to store baseball innings pitched that stores decimal numbers with one decimal place. The decimal places can only end in .0, .1 or .2. For those not familiar with baseball statistics, innings pitched is usually stored as something like 50.1, which means a pitcher pitched 50 full innings and 1/3 of another inning. 50.2 would be 50 full innings and 2/3 of another inning.
So for example, these numbers could be stored in the database: 10.1 26.2 13.2 7.1
28.5 could not be stored in the database, because it ends in .5, and it can only end in .0, .1 or .2.
My issue, is that on my webpage, I am trying to add these numbers to get a total number of innings pitched, but the total isn't correct.
In my example above, technically that adds up to 56.6, when it should add up to 58.0.
Another example would be if I was adding the numbers 28.1, 61.2 and 69.1. That adds up to 158.4 when I need it to add to 159.1.
On example I found online was to take: (3 * totalInnings)/3
but that still doesn't give me what I'm looking for in some cases. Any guidance would be appreciated.
Upvotes: 0
Views: 1523
Reputation: 7490
See innings as separate objects, not as decimal numbers with a different kind of adding. Creating objects is somewhat more work at first, but lay off their advantages when you use the object more often:
Option Explicit
' Constructor function that accept a score as string
Public function new_inning(score)
dim fullScore, partScore
fullScore = split(score, ".")(0)
If instr(score, ".") > 0 then
partScore = split(score, ".")(1)
else
partScore = 0
End if
Set new_inning = (new Inning).Init(fullScore, partScore)
End function
class Inning
private fullScore_, partScore_
Public Property Get FullScore()
FullScore = fullScore_
End Property
Public Property Get PartScore()
PartScore = partScore_
End Property
' Todo: insert some checking of valid scores
Public function Init(fScore, pScore)
fullScore_ = cInt(fScore)
partScore_ = cInt(pScore)
Set init = me
End Function
' Please note, this returns a new inning object so it keeps this object
' away from manipulation
Public Function Add(addInning)
Dim fScore, pScore
fScore = FullScore + addInning.FullScore
pScore = PartScore + addInning.PartScore
if pScore > 2 then
pScore = pScore - 3
fScore = fScore + 1
end if
Set Add = (new Inning).Init(fScore, pScore)
end Function
Public Function ToString()
ToString = cStr(fullScore) & "." & cStr(partScore)
End Function
end class
Dim myInning1, myInning2, resultInning
Set myInning1 = new_Inning("10.1")
Set myInning2 = new_Inning("15.1")
' Adding two innings
Set resultInning = myInning1.Add(myInning2)
Wscript.Echo resultInning.ToString() ' -> 25.2
' Inlining the adding of two innings
wscript.Echo resultInning.Add(new_inning("12.1")).ToString() ' -> 38.0
wscript.Echo resultInning.Add(new_inning("20.2")).ToString() ' -> 46.1
Upvotes: 1
Reputation: 10752
This could probably be improved, but seems to work ok:
There are two functions.
ToThirds converts an innings amount (eg. 10.1) to a more useful number of thirds (there are 31 thirds in 10.1).
ToInnings converts an amount in thirds back to an innings amount.
The first lines (Response.Write...) are your examples which return the same result as you calculated.
<%
Response.Write "<p>" & ToInnings(ToThirds(10.1) + ToThirds(26.2) + ToThirds(13.2) + ToThirds(7.1))
Response.Write "<p>" & ToInnings(ToThirds(28.1) + ToThirds(61.2) + ToThirds(69.1))
Function ToThirds(varInnings)
Dim varNumber, varRemainder
varNumber = Int(varInnings)
varRemainder = varInnings - varNumber
varNumber = (varNumber * 3) + (varRemainder * 10)
ToThirds = varNumber
End Function
Function ToInnings(varNumber)
Dim varInnings, varRemainder
varInnings = varNumber / 3
varRemainder = varInnings - Int(varInnings)
varInnings = Int(varInnings)
If varRemainder = 0 Or varRemainder >=7 Then
varInnings = varInnings & ".0"
ElseIf varRemainder < 4 Then
varInnings = varInnings & ".1"
ElseIf varRemainder < 7 Then
varInnings = varInnings & ".2"
End If
ToInnings = varInnings
End Function
%>
Upvotes: 1