Integer Rounding

This is a discussion on Integer Rounding within the C Programming forums, part of the General Programming Boards category; Hello all! I have a question regarding the rounding of an integer. The integer value is taken from the voltage ...

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    5

    Integer Rounding

    Hello all! I have a question regarding the rounding of an integer. The integer value is taken from the voltage input of the microcontroller (ADC) and is updated every tenth of a second. The integer values ranges from 0 to 4000, but because of voltage fluctuations into the microcontroller the resulting integer value fluctuates around +/- 10 of a certain value.

    What I thought about doing is rounding this value to the nearest 20. For example, if the value is 2337 then the integer value would be rounded to 2340. If the next time the integer value is updated, say to 2345, then it would be rounded down to 2340 again. This would keep the resulting integer value constant despite the value from the microcontroller's ADC fluctuating. The microcontroller can only handle integers.

    I have had a wee think (and a search) but can't really think of a method of achieving this. I'm not that brilliant at programming, but I know the basics. If someone could point me in the right direction I would be very grateful. Thanks.

  2. #2
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    /*

    Seriously?

    How about taking the divisor of the number by, say, 20? So you use integer division to divide the number by 20 (which throws away any "remainder") and then multiply it again by 20 (which, now that the remainder has disappeared will be a nice round multiple of 20).

    You don't even need a function to do this in C. Just an integer division operator and an integer multiplication operator. Gosh, I wonder what they could be?

    */

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,193
    If you have two inputs, one that is 2337 and one that is 2340, how do you know which one should be deemed correct? The short answer to that is that you generally won't.

    How do you know the fluctuations aren't pertinent data? If the ADC is sampling some property of something that varies over time, then the fluctuations might be useful data.

    You are probably better off keeping a running average (i.e. after each sample, compute the sum of all values to date, and divide by the number of samples). Basically that is called "cancelling out the noise" .... when you add values from a fluctuating source together, some of the fluctuations (or noise values) cancel each other out. (This assumes some particular properties of the phenomenon you are measuring, and some particular properties of the noise - neither of which you have mentioned so I'm not going to list other options).

    I also suspect you'll find a discussion of basic sampling theory a bit too daunting at present.
    Right 98% of the time, and don't care about the other 3%.

  4. #4
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Hello, thanks for your answers. I have previously tried ledow's method, but it was not working the way I wanted it to. Take a value of 2335, divide it by 20 = 116.75.. 116 * 20 = 2320. 2335 is closer to 2340, not 2320.

    grumpy, I never mentioned it but these values are averages. The are averaged over 25 values, however the resulting value still fluctuates. This is a result of a high gain instrumentation amplifier amplifying some fluctuations in voltage of a wheatstone bridge circuit. Basic sampling theory is not daunting in the least.

    I may just stick with the method ledow suggested.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,397
    Quote Originally Posted by Possédé
    I have previously tried ledow's method, but it was not working the way I wanted it to. Take a value of 2335, divide it by 20 = 116.75.. 116 * 20 = 2320. 2335 is closer to 2340, not 2320.
    You should modify it slightly to account for the rounding, otherwise you're just truncating.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Ahh, so round the fractional number to the nearest integer then use the resulting integer and multiply by 20. 2335/20 = 116.75 round to 117 * 20 = 2340?

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,397
    You'll still have the rounding problem that way. Adding 10 prior to the division may be a solution, at least for positive values.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,292
    Rounding to the nearest multiple of N isn't a full solution anyway.
    If the value is rapidly fluctuating between 2327 and 2333 say, then with your planned changes it'll instead rapidly fluctuate between 2320 and 2340, which is a bigger jump. So in effect you just made the problem sometimes hidden, but sometimes worse.

    Seriously, grumpy knew what he was talking about. Use a running average to fix this kind of issue. It is the ideal solution.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Quote Originally Posted by laserlight View Post
    You'll still have the rounding problem that way. Adding 10 prior to the division may be a solution, at least for positive values.
    Thanks laserlight. This way produced better results. Thanks to everyone else, and I apologise for asking such a simple question.

  10. #10
    Registered User
    Join Date
    Nov 2011
    Posts
    5
    The sample rate is relativity slow. a 25 position average at 1/10 second sample rate is going to lag quite a lot.

    Looks like you've got a 12Bit ADC. The volts per bit are going to be small. Unless the circuit is very well design, and the ADC is high-quality. the last 3-5 bits are going to be noise, and should not be averaged, just truncated. no need to was resources and introduce lag by averaging noise.

    Also, in a MCU, do the truncation with an & operator. to save cycles.

  11. #11
    Registered User
    Join Date
    Apr 2012
    Posts
    5
    Quote Originally Posted by ekiller200 View Post
    The sample rate is relativity slow. a 25 position average at 1/10 second sample rate is going to lag quite a lot.

    Looks like you've got a 12Bit ADC. The volts per bit are going to be small. Unless the circuit is very well design, and the ADC is high-quality. the last 3-5 bits are going to be noise, and should not be averaged, just truncated. no need to was resources and introduce lag by averaging noise.

    Also, in a MCU, do the truncation with an & operator. to save cycles.
    Thanks for the advice. It is a 10bit ADC (who's values are manipulated to get 0-4000). I apologise for not fully explaining myself in my first post. What it is I've created is a simple cantilever weight measuring device: Wheatstone bridge, strain gauges, amplifier circuit, ADC. I have created it to measure between 0g and 4000g. The value of weight was calculated by finding the linear correlation between weight and ADC value. The introduction of multiplication only multiplies any errors in voltage fluctuations caused by the sensitive bridge circuit. This was the reason to round the resulting weight values to a nearest integer value. Hope that makes a little more sense.

    I found it a little bit insulting the response I got from ledow. If you found my question was insulting your intelligence then you probably shouldn't have responded.

  12. #12
    Registered User
    Join Date
    May 2012
    Posts
    1
    Hi Possédé
    I suspect the source of your trouble is 60 cycle noise. If that's the case, your current sampling rate and averaging scheme won't do you any good. Sampling
    a signal at 10Hz that contains 60Hz noise means you will always sample the noise component at the same point, and all the averaging in the world won't
    remove it. If you change your sample rate to 52mS (or 48mS) and change your average from 25 to 32, most of the noise will be averaged out.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting float to integer... without rounding!
    By hebali in forum C Programming
    Replies: 6
    Last Post: 10-05-2008, 06:58 PM
  2. question in rounding integer in c
    By DrGreat in forum C Programming
    Replies: 5
    Last Post: 04-13-2008, 08:13 AM
  3. Rounding in C
    By blackcell in forum C Programming
    Replies: 13
    Last Post: 02-16-2008, 02:44 AM
  4. Replies: 5
    Last Post: 06-12-2007, 02:18 PM
  5. need help with rounding
    By blindleaf in forum C Programming
    Replies: 1
    Last Post: 02-20-2003, 02:49 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21