iPhone : integer overflow in expression - iphone

I get integer overflow in expression for NSTimerInterval, which is really a double.
NSTimerInterval paymentTermsInMilliSeconds = 30 * 24 * 60 * 60 * 1000;
What's the best way to handle timer interval in iPhone?

This is most likely caused because the calculation is being performed on integers, which is giving an integer result. Try instead to use double values.
EDIT: I just checked, and this is exactly what is happening. If you change your calculation to: NSTimeInterval paymentTermsInMilliSeconds = 30.0 * 24.0 * 60.0 * 60.0 * 1000.0;, then the code gives the correct value of "2592000000". Otherwise, you end up with an overflow and a result of "-1702967296".

You probably mean NSTimeInterval. This is usually a time interval in seconds. To use with milliseconds use 0.001 seconds for milliseconds.

Use,
NSTimerInterval paymentTermsInMilliSeconds = 30 * 24 * 60 * 60 * 1000.0;
Hope, will solve the problem.

Related

Decimal hour shows 4 min 60 seconds not 5 minutes

I think the title says it all but let me go in to it a bit more.
I am storing decimal hours in a DB every 5 minutes while a user uses my app. I am having a bit of trouble displaying the correct time for some of the 5 min blocks in that it shows 4 min and 60 seconds. Every 3rd 5 min block shows this.
So something like this
4:60
10:00
15:00
19:60
Some even have n:59 instead of n:00
Part of the code is:
let hours = Int(floor(decimalHour))
let mins = Int(floor(decimalHour * 60) % 60)
let secs = Int(floor(decimalHour * 3600) % 60)
Any suggestions what I could be doing wrong?
Binary floating point number can not represent all numbers
exactly, therefore your code is prone to rounding errors.
Example (Swift 2):
let decimalHour = 1.0 + 5.0/60.0
print(decimalHour.debugDescription) // 1.0833333333333333
print(floor(decimalHour * 3600)) // 3899.0
let hours = Int(floor(decimalHour))
let mins = Int(floor(decimalHour * 60) % 60)
let secs = Int(floor(decimalHour * 3600) % 60)
print(hours, mins, secs) // 1 5 59
The actual number stored in decimalHour is slightly less than 1 + 5/60, and therefore the seconds are calculated wrongly.
(Also note that you cannot use % with floating point numbers
in Swift 3, compare What does "% is unavailable: Use truncatingRemainder instead" mean?.)
As already said in the comments, a better approach would be
to store the duration as an integer (number of seconds).
If that is not possible, round the floating point number to
a the number of seconds and then continue with pure integer
arithmetic. Example (works with Swift 2+3):
let decimalHour = 1.0 + 5.0/60.0
let totalSeconds = lrint(decimalHour * 3600) // round to seconds
let hours = totalSeconds / 3600
let mins = (totalSeconds % 3600) / 60
let secs = totalSeconds % 60
print(hours, mins, secs) // 1 5 0

MIDI tick to millisecond?

I realize that there are many questions here concerning converting MIDI ticks to milliseconds (ex: How to convert midi timeline into the actual timeline that should be played, Midi Ticks to Actual PlayBack Seconds !!! ( Midi Music), Midi timestamp in seconds) and I have looked at them all, tried to implement the suggestions, but i am still not getting it.
(Did I mention I am a little "math phobic")
Can anyone help me work a practical example? I am using the Bass lib from un4seen. I have all the data I need - I just don't trust my calculations.
Bass Methods
Tick
// position of midi stream
uint64_t tick = BASS_ChannelGetPosition(midiFileStream, BASS_POS_MIDI_TICK)
PPQN
//The Pulses Per Quarter Note (or ticks per beat) value of a MIDI stream.
float ppqn;
BASS_ChannelGetAttribute(handle, BASS_ATTRIB_MIDI_PPQN, &ppqn);
Tempo
//tempo in microseconds per quarter note.
uint32_t tempo = BASS_MIDI_StreamGetEvent( midiFileStream, -1, MIDI_EVENT_TEMPO);
My Attempt at Calculating MS value for tick:
float currentMilliseconds = tick * tempo / (ppqn * 1000);
The value I get appears correct but I don't have any confidence in it since I am not quite understanding the formula.
printf("tick %llu\n",tick);
printf("ppqn %f\n",ppqn);
printf("tempo %u\n",tempo);
printf("currentMilliseconds %f \n", currentMilliseconds);
Example output:
tick 479
ppqn 24.000000
tempo 599999
currentMilliseconds 11974.980469
Update
My confusion continues but based on this blog post I think I have the code right – at least the output seems accurate. Conversely, the answer provided by #Strikeskids below yields different results. Maybe I have an order of operations problem in there?
float kMillisecondsPerQuarterNote = tempo / 1000.0f;
float kMillisecondsPerTick = kMillisecondsPerQuarterNote / ppqn;
float deltaTimeInMilliseconds = tick * kMillisecondsPerTick;
printf("deltaTimeInMilliseconds %f \n", deltaTimeInMilliseconds);
.
float currentMillis = tick * 60000.0f / ppqn / tempo;
printf("currentMillis %f \n", currentMillis);
Output:
deltaTimeInMilliseconds 11049.982422
currentMillis 1.841670
Tempo is in beats per minute. Because you want to be getting a time, you should have it in the denominator of your fraction.
currentTime = currentTick * (beats / tick) * (minutes / beat) * (millis / minute)
millis = tick * (1/ppqn) * (1/tempo) * (1000*60)
to use integer arithmetic efficiently do
currentMillis = tick * 60000 / ppqn / tempo
This works:
float kMillisecondsPerQuarterNote = tempo / 1000.0f;
float kMillisecondsPerTick = kMillisecondsPerQuarterNote / ppqn;
float deltaTimeInMilliseconds = tick * kMillisecondsPerTick;
printf("deltaTimeInMilliseconds %f \n", deltaTimeInMilliseconds);

iPhone: Issue when adding 60 days from the current date in milliseconds

I am trying to add 60 days from the current date in milliseconds. I tried the below code, i'm able to get the current date milliseconds properly, but after adding 60 days milliseconds to current date, its not giving me the expected milliseconds. Please help on correcting what i'm doing wrong here.
double currDateInMilliSecs = [NSDate timeIntervalSinceReferenceDate] * 1000;
NSLog(#"currDateInMilliSecs: %f", currDateInMilliSecs);
double sixtydaysvalue = 60 * 24 * 3600 * 1000;
NSLog(#"sixtydaysvalue: %f", sixtydaysvalue);
double sixtyDaysMilliSecsFromCurrDate = currDateInMilliSecs + sixtydaysvalue;
NSLog(#"sixtyDaysMilliSecsFromCurrDate: %f", sixtyDaysMilliSecsFromCurrDate);
Thank you.
Try
double sixtydaysvalue = 60.0 * 24.0 * 3600.0 * 1000.0;
The value exceeds the max 32-bit int, so you need to perform the calculation in the double type.
You wil try this
NSTimeInterval sixtydaysvalue = 60 * 24 * 3600 * 1000.0

Calculate Pace To String

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.

% operator for time calculation

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;