How would I convert a double value to hh:mm? - objective-c

As it says above...
I don't need the seconds with that as it does not constantly update.
I have searched around this site and google for a few hours and couldn't find anything exactly like what I need.
Here is my code:
//Sets the percentage calculation
double percent = level / 100;
//Calculates the time left while using the following
double a = 40 * percent;
double b = 400 * percent;
double c = 7 * percent;
double d = 6 * percent;
aTime.text = [NSString stringWithFormat:#"%f", a];
bTime.text = [NSString stringWithFormat:#"%f", b];
cTime.text = [NSString stringWithFormat:#"%f", c];
dTime.text = [NSString stringWithFormat:#"%f", d];
After a calculation of, say, 50% of 7 hours, it currently gives 3.5 hours. I want it to say 3:30.
The calculations, as you can see, are static minus the level calculation, I just need to know how to convert the decimal to hh:mm (maybe even days for the 400 hours one).
Note: all the numbers above (40, 400, 7, 6) are in hours.

Example:
double hours = 7;
double percent = 0.5; // 50 percent
int value = hours * percent * 60; // value in minutes
NSString *formatted = [NSString stringWithFormat:#"%02d:%02d",value/60,value%60];
NSLog(#"%#",formatted);
Output:
03:30

Related

Using NSDecimalNumber in for Loop?

I have a loop i am trying to run with NSDecimalNumber values but the value returned is always the same. I understand NSDecimalNumber isn't mutable but i originally used double values and was getting the wrong result at the end which I assume is some floating point error/rounding error. Here is the code:
double balanceAmount = loanAmountValue;
double rtemp = r / (n * 12);
double intA = balanceAmount * rtemp;
double principalA = payfinal - intA;
double principal = balanceAmount - principalA;
NSDecimalNumber *balDeciminal = (NSDecimalNumber *) [NSDecimalNumber numberWithDouble:balanceAmount];
NSDecimalNumber *rTempDecimal = (NSDecimalNumber *) [NSDecimalNumber numberWithDouble:rtemp];
NSDecimalNumber *payFinalDecimal = (NSDecimalNumber *) [NSDecimalNumber numberWithDouble:payfinal];
NSDecimalNumber *principalDecimal = (NSDecimalNumber *) [NSDecimalNumber numberWithDouble:principalA];
for (n = n * 12; n != 0; --n) {
NSDecimalNumber *realBalanceDecimal = [balDeciminal decimalNumberBySubtracting:principalDecimal];
NSDecimalNumber *interestDecimal = [balDeciminal decimalNumberByMultiplyingBy:rTempDecimal];
NSDecimalNumber *principalDecimalAmount = [payFinalDecimal decimalNumberBySubtracting:interestDecimal];
NSString *tempInterest = [NSString stringWithFormat:#"$%#", interestDecimal];
[interestLabels addObject:tempInterest];
NSString *tempPrincipal = [NSString stringWithFormat:#"$%#", principalDecimalAmount];
[pricipalLabels addObject:tempPrincipal];
NSString *tempBalance = [NSString stringWithFormat:#"$%#", balDeciminal];
[balanceLabels addObject: tempBalance];
}
NSLog(#"%#", balanceLabels);
NSLog(#"%#", pricipalLabels);
NSLog(#"%#", interestLabels);
If NSDecimalNumber doesn't allow me to make these sort of calculations could someone suggest something else that will return a result that is accurate?
Thanks!
EDIT : Double Code
double r = interestAmountValue/200;
//NSLog(#"%f", r);
double n = yearAmountValue;
double rPower = pow(1+r, 0.166666666);
double tophalf = rPower - 1;
double nPower = (-12 * n);
double bothalf = pow(rPower, nPower);
double bothalffinal = 1 - bothalf;
double tempfinal = tophalf / bothalffinal;
double payfinal = loanAmountValue * tempfinal;
double totalPaymentd = payfinal * n * 12;
double totalInterestd = totalPaymentd - loanAmountValue;
for (n = n * 12; n != 0; --n) {
double realBalance = balanceAmount - principalA;
double interest = balanceAmount * rtemp;
NSLog(#"%f", interest);
double principalAmount = payfinal - interest;
balanceAmount -= principalA;
}
Hi the problem you were having is that you weren't checking was the loan payed off and you were entering negative numbers meaning the underlying problem is with the spreading of payments.
double loanAmountValue = 100000;
double balanceAmount = loanAmountValue;
double n = 30;
double interestAmountValue = 8;
double r = interestAmountValue/1200;
double rtemp = r/(n*12);
double intA = balanceAmount * rtemp;
//NSLog(#"%f", r);
double rPower = pow(1+r, 0.166666666);
double tophalf = rPower - 1;
double nPower = (-12 * n);
double bothalf = pow(rPower, nPower);
double bothalffinal = 1 - bothalf;
double tempfinal = tophalf / bothalffinal;
double payfinal = loanAmountValue * tempfinal;
double principalA = balanceAmount - intA;
double totalPaymentd = payfinal * n * 12;
double totalInterestd = totalPaymentd - loanAmountValue;
for (n = n * 12; n != 0; --n) {
double realBalance = balanceAmount - principalA;
double interest = balanceAmount * rtemp;
NSLog(#"interest: %f", interest);
NSLog(#"rtemp: %f",rtemp);
double principalAmount = payfinal - interest;
// Check for negative balance
if (balanceAmount < principalAmount) {
NSLog(#"Balance Amount: %f",balanceAmount);
NSLog(#"Months Left: %f",n);
break;
}
balanceAmount -= principalAmount;
NSLog(#"balanceAmount %f",balanceAmount);
}
Using your code with the values of n = 30 years, loanAmountValue = 100000, and interestAmountValue = 8%. I had the loan payed off with 63 months left. I assume r = interestAmountValue/1200 instead of 200 to get percentage per month?
Regarding use of NSDecimal number I don't know what impact floating point precision will have on your corrected mortgage calculator, but the problem you were having was not with using double data types it is with the spreading of payments.
I wonder what makes you think that putting a double into an NSDecimalNumber could somehow create extra precision. And it looks to me that in the loop you are always doing the exact same calculation.
double gives about 15 to 16 decimals of precisions. If you are calculating a loan for 30 years, it is very unlikely that you will run into problems due to not having enough precision. I'd suggest that you post your code with double precision numbers and let people have a look at where you went wrong.
The code needs to be cleaned and checked:
The for loop is not producing a change per iteration.
Use the debugger to figure out why. Perhaps the fact that five variables are not being used is a hint.
The following variables are not used:
intA
principalA
principal
principalDecimal
realBalanceDecimal

Objective-C: How Can I Format a float value to Only Display The Decimal, Without The Full Figure, or Decimal Point?

There are MANY Q&A's for limiting to only 2 decimal places, to the point of over saturation.
However, I would like to format my float to only get the decimal value.
I'm making a stopwatch, and currently have this...
#implementation HudLayer
{
CCLabelTTF *_label;
float timer;
}
-(void)update:(ccTime)delta { if (_isTimerActive)
{
timer += delta;
NSNumber *theDouble = [NSNumber numberWithDouble:timer];
float miliseconds = timer;
int inputSeconds = [theDouble intValue];
int hours = inputSeconds / 3600;
int minutes = ( inputSeconds - hours * 3600 ) / 60;
NSString *theTime = [NSString stringWithFormat:#"%.2d:%.2d:%.2f", hours, minutes, miliseconds];
[_label setString:[NSString stringWithFormat:#"Time: %#", theTime]];
}
}
However, the issue I'm having is that the timer reads out put on to the label showing the full seconds...
00:14:865.35
Instead it should just be:
00:14:05.35
HH:MM:SS.ms
My first thought was to just drop the decimal from the outputted float, and manually calculate seconds as i do hours and minutes...
Any advice? Thanks...
Try following
timer += delta;
float float_seconds = timer;
int seconds = float_seconds;
int hours = seconds / 3600;
int minutes = seconds / 60 % 60;
NSString *theTime = [NSString stringWithFormat:#"%.2d:%.2d:%05.2f", hours, minutes, float_seconds - ( seconds / 60) * 60];
NSLog(theTime);
[_label setString:[NSString stringWithFormat:#"Time: %#", theTime]];

Objective C Maths

How would I go about calculating a compound interest rate, so far I have:
double principal = [[principalLabel text] doubleValue];
NSLog(#"Principal: %lf",principal);
double years = [[yearsLabel text] doubleValue];
NSLog(#"Years: %lf",years);
double months = [[monthsLabel text] doubleValue] / 12;
NSLog(#"Months: %lf",months);
double days = ([[daysLabel text] doubleValue] / 365) / 10;
NSLog(#"Days :%lf",days);
double rate = ([[rateLabel text] doubleValue] / 100);
NSLog(#"Rate: %lf",rate);
double time = years + days + months;
NSLog(#"Time: %lf",time);
double total = pow(principal * (1 - rate), time);
NSLog(#"Total: %lf",total);
double interest = pow(principal * (1 - rate), time) - principal;
NSLog(#"Interest: %lf",interest);
NSString *interestString = [[NSString alloc] initWithFormat:#"%lf",interest];
NSString *totalString = [[NSString alloc] initWithFormat:#"%lf",total];
[interestLabel setText:interestString];
[totalLabel setText:totalString];
So as you can see I have 5 UITextFields for the: principal, rate, years, months, days. At the moment I keep getting some answer that is no where near the actual answer I am after even though my math seems correct I have reviewed my code thoroughly and found no solution.
My desired result is: E.g.
M = P * (1+R)^Y
M = 1000 * (1+0.10)^2
M = 1210
If you place the output from the NSLog messages in your question also, it will be even more helpful to answer your question. Right now an obvious mistake is mentioned below:
In this line of code
double total = pow(principal * (1 - rate), time);
you have 1 - rate, while you need to have
double total = pow(principal * (1 + rate), time);

NSNumber and decimal value

I have an NSNumber like this for example = 1978, i would like to convert this for : 1K9, seconde example : 35700 convert to : 35K7 ( where "k" is kilometers and "M" is meters, how i can do this
thanks
int temp;
NSNumber *yourNumber;//the number you enter from some where
NSString *newValue;
if([yourNumber intValue]>1000){
temp = [yourNumber intValue] % 1000 ;//your number module 1000
newValue= [[temp stringValue]stringByAppendingString:#"K"];
}
Note: I haven't my mac with me, if the [temp stringValue] gives any worning&error please inform me.
Here's how:
NSNumber *initialNumber = [NSNumber numberWithInt:35700];
NSString *resultString = [NSString stringWithFormat:#"%iK%i", floor(initialNumber / 1000), floor((initialNumber % 1000) / 100)];
Basically you can work with the internal number data.
Assuming you are working on a meter-based value, you might want something like this:
NSNumber *sourceValue = ... // your NSNumber value from any source
int meters = sourceValue.intValue;
int km = floor(meters / 1000); // only your kilometers
int sub_km = meters % 1000; // only the part behind the kilometers
int first_sub_km = floor(sum_km / 100); // the first digit of the subrange
NSString *readable = [NSString stringWithFormat:#"%iK%i", km, first_sub_km];
First, you split the meters into <= 1000 and > 1000.
Then you'll just have to put that out formatted, with a K in between.
Write your own subclass of NSNumberFormatter. In this subclass you can implement the calculation logic.
The logic might look like this.
Devide the value by thousend and add your "k"
if you want to have the first digit of hundreds get the thired last digit of your value
return the new string

Objective-c format time left until certain date

I'm creating a countdown timer and I need to printout the time left (hour:minute:seconds) until a specific date. I've found how to get the time interval between Now and the target date but I don't know how to format the time interval as a string. Does NSDateFormater work on NSTimeInterval?
NSTimeInterval is in seconds, use divide and remainder to break it up and format (code untested):
NSString *timeIntervalToString(NSTimeInterval interval)
{
long work = (long)interval; // convert to long, NSTimeInterval is *some* numeric type
long seconds = work % 60; // remainder is seconds
work /= 60; // total number of mins
long minutes = work % 60; // remainder is minutes
long hours = work / 60 // number of hours
// now format and return - %ld is long decimal, %02ld is zero-padded two digit long decimal
return [NSString stringWithFormat:#"%ld:%02ld:%02ld", hours, minutes, seconds];
}
You would first compare two NSDate objects to retrieve the difference in seconds between the two, the NSDate method you should use is
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate
Then you could simply write a function to parse the seconds into hours/minutes/seconds, for example you could use this (untested):
-(NSDictionary*)createTimemapForSeconds:(int)seconds{
int hours = floor(seconds / (60 * 60) );
float minute_divisor = seconds % (60 * 60);
int minutes = floor(minute_divisor / 60);
float seconds_divisor = seconds % 60;
seconds = ceil(seconds_divisor);
NSDictionary * timeMap = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSNumber numberWithInt:hours], [NSNumber numberWithInt:minutes], [NSNumber numberWithInt:seconds], nil] forKeys:[NSArray arrayWithObjects:#"h", #"m", #"s", nil]];
return timeMap;
}
This is code from my project:
-(NSString*)timeLeftString
{
long seconds = [self msLeft]/1000;
if( seconds == 0 )
return #"";
if( seconds < 60 )
return [NSString stringWithFormat:
pluralString(seconds,
NSLocalizedString(#"en|%ld second left|%ld seconds left", #"")), seconds];
long minutes = seconds / 60;
seconds -= minutes*60;
if( minutes < 60 )
return [NSString stringWithFormat:
NSLocalizedString(#"%ld:%02ld left",#""),
minutes, seconds];
long hours = minutes/60;
minutes -= hours*60;
return [NSString stringWithFormat:
NSLocalizedString(#"%ld:%02ld:%02ld left",#""),
hours, minutes, seconds];
}
msLeft --- my function that returns time in milliseconds
pluralString --- my function that provides different parts of format string depending on the value (http://translate.sourceforge.net/wiki/l10n/pluralforms)
Function returns different format for different timer values (1 second left, 5 seconds left, 2:34 left, 1:15:14 left).
In any case, progress bad should be visible during long operation
One more thought: In case that time left is "small" (less then a minute?), probably time left should not be shown --- just progress bar left to reduce interface "visual noise".