HiveBrain v1.2.0
Get Started
← Back to all entries
snippetMinor

How To Subtract CBOT Grain Prices

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
howsubtractpricescbotgrain

Problem

I had to calculate the difference between Chicago Board of Trade grain futures prices using VB.net and came up with the following (admittedly clunky) solution. It's a little tricky because CBOT prices, as posted, mix octal and decimal numbers. Anyway, here is my code for you to enjoy and tear apart:

```
Public Function GrainSubtraction(ByVal numberOne As Double, ByVal numberTwo As Double) As Double

' This is a somewhat convoluted function to subtract CBOT grain prices ... but it seems to work
' It assumes the numbers have no decimals - that is, if the price of corn is $4.75 3/4 per bushel, this number is represented as 4756 where the last digit (6) represents 6/8

' Basically, we perform octal subtraction on the smallest unit digit and regular decimal subtraction on the remaining digits
' I use arrays to do this so I can isolate each digit - there is probably a more efficient way to do this, though - I'm not a quant

Dim tempOne As Double = 0.0
Dim tempTwo As Double = 0.0

Dim inverted As Boolean = False 'Flags whether the second number is larger than the first
Dim answer As Double = 0.0 ' This will be our ultimate response
Dim multiplier As Double = 1.0

' Here, we compare the two numbers and invert them if the second number is largest then the first

If numberOne = numberTwo Then Return 0.0

If numberOne lengthTwo Then numberLength = lengthOne Else numberLength = lengthTwo

' Create our array
Dim numberOneArray(numberLength) As Integer
Dim numberTwoArray(numberLength) As Integer
Dim answerArray(numberLength) As Integer ' This will hold our answer as an array

' Set Array Values To Zero
For I = 0 To numberLength - 1
numberOneArray(I) = 0
numberTwoArray(I) = 0
Next

For I = 0 To lengthOne - 1
numberOneArray(I) = tempOne Mod 10
tempOne = Int(tempOne / 10)
Next

For I = 0 To lengthTwo - 1
numberTwoArray(I) = tempTwo Mod 10
tempTw

Solution

The following will shorten your code considerably:

Public Function GrainSubtraction(ByVal numberOne As Double, ByVal numberTwo As Double) As Double
    Dim Dec1 As Integer = CInt(Int(numberOne / 10.0))
    Dim Oct1 As Integer = CInt(numberOne - (Dec1 * 10))
    Dim Dec2 As Integer = CInt(Int(numberTwo / 10))
    Dim Oct2 As Integer = CInt(numberTwo - (Dec2 * 10))
    Dim ResultDec, ResultOct As Integer
    If Oct1 < Oct2 Then
        Dec1 -= 1
        ResultOct = CInt(7 - (Oct2 - Oct1))
    Else
        ResultOct = CInt(Oct1 - Oct2)
    End If
    ResultDec = CInt(Dec1 - Dec2)
    Return CDbl((Math.Abs(ResultDec * 10) + ResultOct) * Math.Sign(ResultDec))
End Function


This does simple octal subtraction on the last digits of the numbers supplied and decimal subtraction on the rest. I left the parameters and the return type as doubles but it would make more sense to have them as integers, since that's what they basically are.

Code Snippets

Public Function GrainSubtraction(ByVal numberOne As Double, ByVal numberTwo As Double) As Double
    Dim Dec1 As Integer = CInt(Int(numberOne / 10.0))
    Dim Oct1 As Integer = CInt(numberOne - (Dec1 * 10))
    Dim Dec2 As Integer = CInt(Int(numberTwo / 10))
    Dim Oct2 As Integer = CInt(numberTwo - (Dec2 * 10))
    Dim ResultDec, ResultOct As Integer
    If Oct1 < Oct2 Then
        Dec1 -= 1
        ResultOct = CInt(7 - (Oct2 - Oct1))
    Else
        ResultOct = CInt(Oct1 - Oct2)
    End If
    ResultDec = CInt(Dec1 - Dec2)
    Return CDbl((Math.Abs(ResultDec * 10) + ResultOct) * Math.Sign(ResultDec))
End Function

Context

StackExchange Code Review Q#29755, answer score: 3

Revisions (0)

No revisions yet.