I am trying to calculate pace (min/mi) and format it as mmmm:ss.
So far I calculate my pace into a float by taking 60 and dividing it by my average speed. At an average speed of 76mph, my average pace is displayed as 0.79. I want to format it so that it converts my 0.79 minutes to mmmm:ss (thus showing my average pace as 0000:47). How can I do this?
double milesPerHour = 76.0;
int secondsPerMile = (int)round(3600.0 / milesPerHour);
NSString *paceString = [NSString stringWithFormat:#"%04d:%02d", secondsPerMile / 60, secondsPerMile % 60];
Not sure if I get your question right, but this is pretty much just math.
You can get the minutes by rounding your value (0.79 in this case) down and you can get seconds by taking your value, subtracting the minutes from it and multiplying that by 60.
So if you'd need 2.35 minutes for a mile, you'd have 2 minutes and 0.35*60 = 21 seconds.
Related
in my app i need to submit the time to the game center and i need to show that in Elapsed Time - To the hundredth of a second format.
00:00:00.00
this is the format i want to show in leader board.
In my app im getting the time in following format
ss.SS
ss = seconds
SS = hundredth of a second
i converted the value to double before send it to the game center
double newScoreDouble = [newScore doubleValue];
But when i sending the double score to the game center it asking me to convert it to int64_t format. But when i convert it to that format it loses some part of the double value.
double intPart = 0;
double fractPart = modf(newScoreDouble, &intPart);
int isecs = (int)intPart;
int min = isecs / 60;
int sec = isecs % 60;
int hund = (int) (fractPart * 100);
int64_t time_to_send_through_game_center = min*6000 + (sec*100 + hund);
this is the way i convert double to int64_t
Can any one say how to send whole double value to the game center and display it in Elapsed Time - To the hundredth of a second format.
Thanks
I've done this before. When you're recording a score in the to the hundredth of a second format. You would multiply your seconds with a hundred before submitting.
So let's say the user scored 1minute 44 seconds 300 milliseconds : 1:44:30 = 104.3 seconds. Then you would set your value property of GKScore object equal to 104.3 * 100 = 10430 ,and submit it like that.
Give it a try :)
I am developing an app and want to round off values
i.e if the output is 4.8 I want to display 4.8
while if the output is 4.0 , I want to display 4
Also, it would be great if I could precisely round values : as in if value is 4.34 then round to 4.3 while if its 4.37 then round it to 4.4
One way to round floating point values is to just add 0.5 and then truncate the value.
double valueToRound = GetTheValueFromSomewhere();
double roundedValue = (double)((int)(valueToRound + 0.5));
This will round 1.4 down to 1.0 and 1.5 up to 2.0 for example. To round to other decimal places as you mentioned, simply multiply the initial value by 10, or 100, etc. use the same sort of code, and then divide the result by the same number and you'll get the same result at whatever decimal place you want.
Here's an example for rounding at an arbitrary precision.
double valueToRound = GetTheValueFromSomewhere();
int decimalPrecisionAtWhichToRound = 0;
double scale = 10^decimalPrecisionAtWhichToRound;
double tmp = valueToRound * scale;
tmp = (double)((int)(tmp + 0.5));
double roundedValue = tmp / scale;
So, if decimalPrecisionAtWhichToRound is set to 0 as in the above it'll round to the nearest whole integer. 1.4 will round to 1.0. 1.5 will round to 2.0.
If you set decimalPrecisionAtWhichToRound to 1, it would round to the nearest tenth. 1.45 would round to 1.5 and 1.43 would round to 1.4.
You need to first understand how to do rounding on paper, without someone showing you the code to do it. Write down some numbers and figure out how to round them.
To round to a specific decimal position you add half the value of that position and then truncate. Ie, 1.67 + 0.05 = 1.72 then truncate to 1.7.
But there are two tricky things in programming that aren't there when you do it on paper:
Knowing how to truncate -- There are several ways to do it while programming, but they're non-trivial.
Dealing with the fact that floating-point numbers are imprecise. Ie, there is no exact representation of, say, 1.7, but rather the two closest numbers are apt to be something like 1.69998 and 1.700001
For truncating the trick of multiplying the number by the appropriate power of 10 to produce an integer works pretty well. Eg, (1.67 + 0.05) * 10 = 17.2, then convert to int to get 17, then convert back to float and divide by 10 to get 1.7 (more or less). Or (if you're printing or displaying the value) just format the integer number with the decimal point inserted. (By formatting the integer value you don't have to deal with the problem of imprecise floating point representations.)
If you want to suppress trailing zeros it gets a bit trickier and you probably have to actually write some code -- format the number, then scan backwards and take off any trailing zeros up to the decimal point. (And take the decimal point too, if you wish.)
float number=17.125;
NSNumberFormatter *format = [[NSNumberFormatter alloc]init];
[format setNumberStyle:NSNumberFormatterDecimalStyle];
[format setRoundingMode:NSNumberFormatterRoundHalfUp];
[format setMaximumFractionDigits:2];
NSString *temp = [format stringFromNumber:[NSNumber numberWithFloat:number]];
NSLog(#"%#",temp);
double myNumber = 7.99;
NSString *formattedNumber = [NSString stringWithFormat:#"%.*f",
fmod(round(myNumber * 10), 10) ? 1 : 0, myNumber];
I'm writing an application that uses AVFoundation and CMTime. I have logged the values of my CMTime instances created using CMTimeMake(). This value seems to be rounded to the nearest integer. I need a CMTime instance with a precise value, without rounding.
I have seen the rounding constants in the CMTime reference:
enum {
kCMTimeRoundingMethod_RoundHalfAwayFromZero = 1,
kCMTimeRoundingMethod_RoundTowardZero = 2,
kCMTimeRoundingMethod_RoundAwayFromZero = 3,
kCMTimeRoundingMethod_QuickTime = 4,
kCMTimeRoundingMethod_RoundTowardPositiveInfinity = 5,
kCMTimeRoundingMethod_RoundTowardNegativeInfinity = 6,
kCMTimeRoundingMethod_Default = kCMTimeRoundingMethod_RoundHalfAwayFromZero
};
There aren't any example of how I can control which of these strategies is applied to a CMTime instance? Or, if this isn't the right way, how can I extract a precise value from a CMTime instance?
Edit:
I have found and tested CMTIME_HAS_BEEN_ROUNDED(). I passed my CMTime instance to this function and it returns No (indicating that the value has not been rounded). So why am I losing precision?
If you read the documentation for CMTime you will see that it stores time as a rational number using a numerator and denominator. The numerator is int64_t while the denominator is int32_t.
The numerator specifies how many "ticks" have passed, and the denominator specifies how many "ticks" per second.
So 0.5 seconds can be stored as:
100/200: 100 ticks, 200 ticks per second
500/1000: 500 ticks, 1000 ticks per second
8/16, 8 ticks, 16 ticks per second
And so forth. The way you have done it, using
CMTimeMake([[Array objectAtIndex:i]floatValue], 1);
Is saying "there is one tick per second", and since the numerator is an integer, the float value is truncated so only the 1 is stored. Therefore you are specifying time as: 1/1, one tick has elapsed, one tick per second, so you are actually storing exactly 1 second.
To fix this, it depends on what you want to do and whether you care about the timescale. Apple recommends a timescale of 600, but if you don't care, you can just do this:
CMTimeMake([[Array objectAtIndex:i]floatValue]*1000, 1000);
That sets timescale to 1000, so 1000 ticks per second, so one millisecond per tick. It also converts the time in seconds to milliseconds. Note that it truncates the 4th digit, so if you had 1.2345 you just get 1.234 not 1.235. If that matters to you, see roundf.
CMTimeMake([[Array objectAtIndex:i]floatValue]*1000, 1000);
This helped me to get exact time in milliseconds. Cheers.
Problem:
I am plotting a time series. I don't know apriori the minimum & maximum values. I want to plot it for the last 5 seconds of data. I want the plot to automaticaly rescale itself to best fit the data for the past five seconds. However, I don't want the rescaling to be jerky (as one would get by constantly resetting the min & max) -- when it does rescale, I want the rescaling to be smooth.
Are there any existing algorithms for handling this?
Formally:
I have a function
float sample();
that you can call multiple times. I want you to constantly, in real time, plot the last 5 * 60 values to me, with the chart nicely scaled. I want the chart to automatically rescale; but not in a "jerky" way.
Thanks!
You could try something like
float currentScale = 0;
float adjustSpeed = .3f;
void iterate() {
float targetScale = sample();
currentScale += adjustSpeed * (targetScale - currentScale);
}
And lower the adjustSpeed if it's too jerky.
I am trying to display minutes and seconds based on a number of seconds.
I have:
float seconds = 200;
float mins = seconds / 60.0;
float sec = mins % 60.0;
[timeIndexLabel setText:[NSString stringWithFormat:#"%.2f , %.2f", mins,seconds]];
But I get an error: invalid operands of types 'float' and 'double' to binary 'operator%'
And I don't understand why... Can someone throw me a bone!?
A lot of languages only define the % operator to work on integer operands. Try casting seconds and mins to int before you use % (or just declare them int in the first place). The constant values you use will also need to be int (use 60 instead of 60.0).
As others have pointed out, you should be using integers. However, noone seems to have spotted that the result will be incorrect. Go back and have another look at modulo arithmetic, and you'll realize you should be doing
int seconds = 200;
int mins = seconds / 60;
int sec = seconds % 60;
Note the last line, seconds % 60 rather than mins % 60 (which will return the remainder of the minutes divided by 60, which is the number of minutes to the hour, and completely unrelated to this calculation).
EDIT
doh, forgot the ints... :)
The 60.0 forces a conversion to double
try:
float seconds = 200;
float mins = seconds / 60;
float sec = mins % 60;
Use ints instead. At least in your example, seems like they're enough (it will also be faster and clearer).
Also, in this case you would get 3.3333... mins, and not 3 minutes as expected. You could use Math.ceil(x) if you need to work with floats.
Do like this:
float seconds = 200.5;
float mins = floor(seconds / 60.0);
float sec = seconds - mins * 60.0;