user2762748
user2762748

Reputation: 351

Decimal Calculations in ASP/VBScript

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

Answers (2)

AutomatedChaos
AutomatedChaos

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

johna
johna

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

Related Questions