NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » Quick question for those fluent in C
June 06, 2010 by Rick_S |
I have a quick question for those fluent in C. In a program I wrote, I use type casting (I think thats the right verbage??) to get just the integer portion of a math function. For example in this program posted in another topic on the forum I do the following. First I declare my variables as the type I want.
And then later in the program I do the following math (cnt can be any value between 0 and 9999)
This way, if cnt = 5320, ones becomes 0, tens becomes 2, hund becomes 3 and thou becomes 5. Is this a proper way to do this type of parsing or can this cause other problems? Is there a better way? Thanks, Rick |
---|---|
June 06, 2010 by mrobbins (NerdKits Staff) |
Hi Rick, That's a perfectly fine way of doing it -- I don't think there's any "better" way of converting from a (binary) integer field to a bunch of decimal digits. Just as an academic curiousity, if you wanted to save a few CPU cycles, you could probably replace all of the / lines with subtractions:
This will be faster because the AVR has built-in instructions for addition, subtraction, and multiplication, and these can be done in 1 or 2 clock cycles (for 8-bit fields). In contrast, division and the % operator have to be performed with a bunch of operations. But the result will be the same, and you're probably not really pressed to save such few cycles! If you want another example, the "lcd_write_int16" function in the libnerdkits/lcd.c file is an example of a slightly more complicated version of this idea. It has to deal with variable-decimal-length numbers, as well as negative numbers, but it's basically doing the same thing as your code. In summary, your code is just fine! Mike |
June 06, 2010 by Rick_S |
If I did the subtractions though, it wouldn't shift the digits would it? In my examble above, if cnt = 5320 wouldn't it work as follows?
Or am I seeing this wrong? Is there a better way to drop a digit without division? |
June 06, 2010 by mrobbins (NerdKits Staff) |
Hi Rick, You're right -- I got turned around somewhere! How about:
This one has 3 divisions, 3 multiplications, and 3 subtractions. Your original one had 3 divisions and 3 modulo (%) operations (which I believe to be about as expensive as division). Just for reference, a 16x16 bit multiplication takes roughly 15 to 20 clock cycles with the hardware multiplier, while a 16/16 bit division might take roughly 150-200 clock cycles. That's a big difference, so when speed counts, avoid division! (The important exception is that dividing by any power of 2 is "cheap" because it's really just a shift in binary.) But in any case, your original code works, and more importantly you understand it, so just stick with it until you really need the speed! Sorry for the confusion. Mike |
June 06, 2010 by Rick_S |
No problem at all, I was just excited to figure out the code to drive the 595 shift registers relativly painlessly. Also, I didn't realise there was such a difference between Multiplication and division Clock cycle wise. One last thing, When you wrote the line
does that temporarily cast the variable thou as 16 bit on the fly? And if so, why is it necessary? Does something bad happen if variables of mixed types are used in an operation? Or does that ensure that the compiler will do 16 bit math? Rick |
June 06, 2010 by mrobbins (NerdKits Staff) |
Hi Rick, I'm just in the habit of explicitly specifying when I want the compiler to interpret something as a larger bit width because I've occasionally been burned in the past when the compiler makes the wrong assumption. I think it's almost certainly going to use 16-bit math in this case (even without my cast to uint16_t), since the constant parameter is >255 and the result is going into a 16-bit field, but I've just gotten into the habit of doing this explicit casting when mixing different size fields in arithmetic. Mike |
June 13, 2010 by BobaMosfet |
mrobbins- I'm with you on that one. I learned a long time ago to be very careful with compilers and optimization options. I've even run into problems where low-level debuggers (we called them 'monitors'-- If you've ever heard the statement 'break into the monitor', that's what it means) incorrectly altered object-code before letting it run on a CPU. BM |
Please log in to post a reply.
Did you know that our USB NerdKit works on Windows, Linux, and Mac OS X? Learn more...
|