snippetMinor
How To Subtract CBOT Grain Prices
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
```
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:
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.
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 FunctionThis 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 FunctionContext
StackExchange Code Review Q#29755, answer score: 3
Revisions (0)
No revisions yet.