iOS: NSDecimalNumber calculations and accuracy with currencies - ios

I'm calculating back and forth some values and that's where I get the problem. Let's say you have a yearly amount of 100 Dollar and save them as as monthly value to CoreData using decimalnumbers:
[self.sumPerMonth decimalNumberByAdding:[amount decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:#"12"]]];
Ok so my 100 Dollars are now 8.33333333333333.... Now in some places in my app I want to get the value back to yearly. So if I calculate now 12*8.33333333 I don't get 100 but something very close: 99.999999999999999999999999999999999996.
For a progress bar I'm doing this and this results in 100% which is what I actually want (moneySpent being 100 and budget being 99.999999999999999999999999999999999996):
[[moneySpent decimalNumberByDividingBy:budget] doubleValue]
But if I'm doing this (budgetLeft being budget-moneySpent):
[budgetLeft compare:[NSDecimalNumber zero]] == NSOrderedAscending
This results in TRUE, which is wrong. With currencies this should be 0 because 99.999999...6 should be 100.
So how would you handle this? I'm a bit confused...should I only compare using doubleValues? Or should I always round the NSDecimalNumbers or what?

You can use the decimalNumberByRoundingAccordingToBehaviour: method of NSDecimalNumber whenever you need to round back to 'currency'. The NSDecimalNumberBehaviours protocol allows you to specify the rounding mode and the scale (decimal places) - so you can round to two decimal places whenever you need an actual currency amount - typically at the end of any calculations.

Related

Metastock to MQL4 conversion

I would like to know how I can use the Ref() function of metastock in MQL4.
Ref() in metastock is used to take the previous values of the given data array.
for example:
Ref(C,-1)
gives the value of previous day's close.
iClose(_Symbol,PERIOD_D1,1) for close. In Mql4 0 means the current candle, and increases to the left, so -1 in your case becomes 1; this is true when accessing candle data. For regular arrays, e.g., obtained by CopyBuffer or looping, array indexes are 0 to ArraySize()-1

Calculating a simple decimal in rails console using postgresql

Ok...I think I'm missing something very obvious here but haven't been able to google myself through this solution. I have two simple rails methods that calculate the number of up votes and down votes. They will always return a fraction because i'm trying to show a percentage (up_vote_count / votal_vote_count). I open the rails console and run the following:
y = #somespecificrecord
then...
y.up_vote_count
This returns 1 as is expected
y.down_vote_count
This returns 1 as is expected
y.total_vote_count
This returns 2 as is expected.
However, when I run in the console...
y.up_vote_count / y.total_vote_count
This returns 0 when it should return .50. I've been reading about floats/integers/decimals, etc and I do see this in the schema on the model i'm working from:
t.float "value", default: 0.0
Is this my problem?...and if so what do I have to do to allow myself to do a simple formula like the one above in rails console that will return the correct decimal rounded to 2 digits (i.e, .50 in this case above). I don't know if I want to run any migrations to change data types because this is a gem (& as a beginner I tend to stay away from customizing code from any gems I'm using). Is there another way? something small i'm missing hopefully?
UPDATE:
I'm learning decimals are slower than floats also, so is there any way to accomplish this with continuing to use t.float "value", default: 0.0
thanks for any help.
1 / 2 = 0.5
With integers this will round down to 0
You can get around this by casting the divisor to a float, forcing it to do division with floating point accuracy.
y.up_vote_count / y.total_vote_count.to_f
Float
Float objects represent inexact real numbers using the native
architecture's double-precision floating point representation.
Floating point has a different arithmetic and is an inexact number.
its important to know if you divide 2 hole numbers you are going to get a hole number.
if you are looking a decimal you should first convert your numbers to a decimal or a "float" like this
up_votes = y.up_vote_count.to_f
total_vote = y.down_vote_count.to_f
(up_votes / total_vote) * 100.0
I hope that this helps

Latitude and Longitude conversion

I need to convert a latitude in ddmm.mmmmm (minutes in 4 decimal places) to ddmm.mmmmmm (minutes in 5 decimal places) format. Is there any good formula to convert this ?
I got the answer
We need to follow these steps for this conversion
1. Convert value in ddmm.mmmm format to dd.ddddddd by using the following formula
dd.ddddddd = dd + ( mm.mmmm / 60 )
convert back
ddmm.mmmmm = concat(dd, (.dddddd * 60))
Example:
To convert 3323.8733 from ddmm.mmmm format
convert to degrees (dd.dddd) format
33 + (23.8733 / 60 ) = 33.397888333333334
convert back to ddmm.mmmmm format
multiply decimal part by 60 i.e 0.397888333333334 * 60 => 23.87330000000004
append with degree
3323.87330000000004
As we need ddmm.mmmmm we can round of 5 decimal places i.e 3323.87330
Sans other information I would recommend following mkk's advice.
If you want to convert "ddmm.mmmmm" (4 decimal places) to "ddmm.mmmmm" (5 decimal places), you should probably just add a zero to the end.
Other methods may appear to give a more satisfactory result by placing a non-zero value in the fifth decimal place. But they cannot add more information than was present in the original number. There is, however, the potential to lose information through loss of significance in mathematical calculations.

Actionscript rounding bug when dividing then multiplying

I am doing the following in actionscript in Coldfusion Flash Forms:
90 / 3.7
Gives me:
24.3243243243243
Whereas the calculator gives me:
24.32432432432432
Note the extra 2 at the end.
So my problem occurs when I am trying to get the original value of 90 by taking the 24.3243243243243 * 3.7 and then I get 89.9999999999 which is wrong.
Why is Actionscript truncating the value and how do I avoid this so I get the proper amount that the calculator gets?
Thanks so much.
Round your number using a routine like this
var toFixed:Function = function(number, factor) {
return (Math.round(number * factor)/factor);
}
Where the factor is 10, 100, 1000 etc, a simple way to think about it is the number of 0's in the factor is the number of decimal places
so
toFixed(1.23341230123, 100) = 1.23
Good explanation of numeric in ActionScript can be found at http://docstore.mik.ua/orelly/web2/action/ch04_03.htm. See section 4.3.2.1. Floating-point precision
A relavant quote:
"In order to accommodate for the minute discrepancy, you should round your numbers manually if the difference will adversely affect the behavior of your code. "

ruby on rails int to minutes::seconds::milliseconds

I have this line, which shows the minutes and seconds. But I have to add milliseconds to it as well for greater accuracy. How do I add that in this line, or is there an easier way to get the desired result?
#duration = [cd.ExactDuration/60000000, cd.ExactDuration/1000000 % 60].map{|t| t.to_s.rjust(2, '0') }.join(':'))
The exact duration type is saved in microseconds. So the first converts to microseconds to minutes, the second part is microseconds to seconds. Now I need to add milliseconds.
cd.ExactDuration/1000 % 1000 should do the trick.
Of course you may also want to tweak the formatting, since that's a datum you don't want to right-justify in a 2-wide field;-). I'd suggest sprintf for string-formatting, though I realize its use is not really intuitive unless you come from a C background.

Resources