1

Probably something stupid, but I can't figure out how to work with these large numbers, then cast the result (which will be small) to an integer. I keep getting negative numbers, which I think means I'm overflowing somewhere.

int freq = 440;
int len = 256;
long timer = 2000000.0 / (freq * len);
int roundedTimer = int(timer);

I should get 18, but I'm getting -108...

3
  • Well, I'm not sure I exactly understand why, but it seems that the result of freq * len needs to be explicitly a long too: long timer = 2000000L / ((long) freq * len); – JeffThompson Jan 25 '16 at 18:09
  • 1
    Majenko has the reason - your divisor calculation overflowed. Either your solution (as coded above) or his, works. Casting either freq or len to long forces the other to be promoted to long for the calculation, and the long result to be used for division. However the solution you described (not the one you coded) would fail. You do have to calculate the divisor as a long. Casting the product comes to late; it will already have overflowed. – JRobert Jan 25 '16 at 18:21
  • The "answer" by JeffThompson is really a comment on Majenko's answer. I'm going to convert it into a comment for you. Please only use answers for answers to the posted question. – Nick Gammon Jan 25 '16 at 20:21
3

freq * long, since they are both integers, are calculated as integers.

440*256=112640 - in binary that is 1 1011 1000 0000 0000 and trimmed to 16 bits becomes 1011 1000 0000 0000 which is -18432 and that is where the heart of your problem is. Unless you explicitly say otherwise the Arduino's compiler does all calculations (except floating point) as 16-bit signed integers.

By casting the values to long it forces the compiler to 'overflow' the 16-bit limit and use a 32-bit limit instead:

long timer = 2000000 / ((long)freq * (long)len);

Another alternative is to define freq and len to be long from the outset instead of int.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.