Reputation: 93434
I have a particular application that needs to calculate something very specific, and while I excel at logic, math has always been my weak spot.
Given a number, say -20, it needs to apply a calculation of a 100 base (that is, the base is 100, not 0. not to be confused with base 100 which would be something else totally).
In other words, the math works like this ..., 105, 104, 103, 102, 101, 100, -101, -102, -103, -104, -105, ...
Then I need to do the math based on this 100 base figure.
So, for example:
-140 - 20 = 120
-120 - 20 = 100
-115 - 20 = -105
-110 - 20 = -110
-105 - 20 = -115
100 - 20 = -120
120 - 20 = -140
If it helps, the problem is related to sports odds. In theory, this refers to money (risk $1.40 to win $1.00 on one side, risk $1.00 to win $1.20 on the other, the .20 difference is what casinos call "the juice" or their cut of moving money back and forth.) However, the program is not dealing with real money, it's more of a simulator.
My current formula works like this:
decimal CalculateSides(decimal side, decimal vig)
{
decimal newSide = side - vig;
newSide = -(newSide < 0) ? newSide + 100 : newSide - 100;
return (newSide < 0) ? newSide + 100 : newSide - 100;
}
While this formula works, I'm not very happy with the conditional +/-, but this is basically the only formula that works for me.
Can anyone suggest a way to improve this? Preferably without conditions of +/-?
EDIT:
When I asked the question, I knew one possible answer was "It's probably best the way you're doing it", and that seems to be the consensus.
Upvotes: 1
Views: 290
Reputation: 10122
The 'sign' solution could be more elegant:
decimal CalculateSides(decimal side, decimal vig)
{
decimal res = side - vig + (100 * Math.Sign(side));
return res + (100 * Math.Sign(res));
}
please note that your algorithm doesn't apply to your given examples.
Upvotes: 0
Reputation: 24177
I strongly suspect that your sample function is broken. Is it a copy paste or did you retyped it ?
decimal CalculateSides(decimal side, decimal vig)
{
decimal newSide = side - vig;
newSide = -(newSide < 0) ? newSide + 100 : newSide - 100;
return (newSide < 0) ? newSide + 100 : newSide - 100;
}
Just try with CalculatesSides(115, 20) you get -95, unlikely to be what you want. (I I understand well result should be -105).
However what you where trying to write seems clear enough. I believe it should be:
decimal CalculateSides(decimal side, decimal vig)
{
decimal newSide;
side = (side < 0) ? side + 100 : side - 100;
newSide = side - vig;
return (newSide < 0) ? newSide - 100 : newSide + 100;
}
This is quite straightforward and won't be easy to optimize
You can do some tricks based on signs to avoid the tests as other suggested, but the result will be quite obfuscated and probably slower.
My advice would be to leave it that way.
Upvotes: 2
Reputation: 56772
One sensible way to handle this would be to compute internally with ordinary numbers which go from positive to negative at zero, and only add/subtract 100 for presentation.
Upvotes: 6
Reputation: 881423
Optimization is generally done to make something run faster. Have you actually found that your code is not running fast enough? I suspect not.
If your code generates the right results and does it in such a way that it doesn't take a great deal of time, leave it alone, and concentrate on other code that's an actual rather than a perceived, problem.
If you're just worried about the way it looks, add some comments to explain how it works. You would most likely have to do that anyway with a one-formula solution so you may as well not waste your effort.
Upvotes: 1