Rounding an Integer up only

Hello,

I need to round up an Integer result to the nearest Thousand. Example

11245 needs to = 12000

11655 needs to = 12000

13190 = 14000
so on and so forth.

My result number range will be from 950 to 36877 , Is this type of rounding function available?

Thanks
Rob

Divide by 1000

Add 1

Multiply by 1000

You should also think about what will happen with zero and negative inputs.

MorganS:
Divide by 1000

Add 1

Multiply by 1000

You should also think about what will happen with zero and negative inputs.

does not work for 11000 (any rounded number) as I assume that should stay 11000

long roundUp(long val)
{
  long rem = val % 1000;
  val -= rem;
  if (rem > 0) val += 1000;
  return val;
}

This can be made generic for all multiples

long roundUp(long val, long factor)
{
  long rem = val % factor;
  val -= rem;
  if (rem > 0) val += factor;
  return val;
}

Code does not work for the largest numbers as there overflow would occur, but that would be true for any algorithm.

Negative numbers not tested yet. What is the behaviour you want? (in your post you define only a positive range)

  1. rounding up towards positive inf -11111 -> -11000 (that is what above code does)
  2. rounding up towards negative inf -11111 -> -12000

Testsketch to show proper working.

//
//    FILE: roundUp.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: demo
//    DATE: 2015-12-05
//     URL: http://forum.arduino.cc/index.php?topic=363883.0
//
// Released to the public domain
//

void setup()
{
  Serial.begin(115200);
  Serial.print("Start ");
  Serial.println(__FILE__);

  for (int x = 1; x <= 1000; x++)
  {
    for (int y = 1; y <= 25; y++)
    {
      Serial.print("\t");
      Serial.print(roundUp(x, y));
    }
    Serial.println();
  }

  for (int x = -50; x <= 50; x++)
  {
    for (int y = 1; y <= 25; y++)
    {
      Serial.print("\t");
      Serial.print(roundUp(x, y));
    }
    Serial.println();
  }
  Serial.println("done");
}

void loop()
{
}

long roundUp(long val, long factor)
{
  long rem = val % factor;
  val -= rem;
  if (rem > 0) val += factor;
  return val;
}

Why not do it like this? (no test needed)

int n= 11000;
int up= ((n+999)/1000)*1000;

kind regards,

Jos

@Jos, works perfectly in positive domain, in the negative domain it fails.

int n = -11000;
int up= ((n+999)/1000)*1000;

up ==> n+999 => -10001 / 1000 => -10 * 1000 = -10000
QED

Furthermore the function (inlined) is ~10% faster on AVR as it uses only one DIV/MUL operator while formula uses two. (that are the expensive ones, esp DIV) But yes that will only matter when performance is an issue.

micros() for 25000 calls
1001024
1108856

Let me go into a little more specific explanation. I have a control panel that shows altitude in increments of a 1000ft adjusted by turning a knob which is hooked to a position sensor. The sensor outputs an angle which I want to convert to the altitude shown on the front of the panel. It reads from 1000 to 37000 ft Here is the map function part of my code.

Alt = map(deg, 92, 187, 1000, 37000);

I guess another option might be an Array?

Thanks for any ideas,
Rob

737nut:
Let me go into a little more specific explanation. I have a control panel that shows altitude in increments of a 1000ft adjusted by turning a knob which is hooked to a position sensor.
Rob

Sorry, but actually, that's not very specific. What do the digits look like? Does it actually display only 1-37 and the "000" is a hard printed mask, or what? Is it an analogue or digital display? Also, why are the answers that were given to your question not applicable?

(I can now see why negative values are not relevant...) :slight_smile:

737nut:
Let me go into a little more specific explanation. I have a control panel that shows altitude in increments of a 1000ft adjusted by turning a knob which is hooked to a position sensor. The sensor outputs an angle which I want to convert to the altitude shown on the front of the panel. It reads from 1000 to 37000 ft Here is the map function part of my code.

Alt = map(deg, 92, 187, 1000, 37000);

I guess another option might be an Array?

Thanks for any ideas,
Rob

How accurate is that angle?
Is it correct to map it in a linear way? gonio math is seldom linear...

As you have only 95 angles a lookup table might just work.

byte lut[95] = { 1,1,2,2, ...37 }; // could be in PROGMEM
...
lcd.print(lut[deg-92]*1000);

Its works! Thanks guys!! So simple I overlooked it. Here is the code that works flawlessly,

LO = map(deg, 92, 187, 1000, 37000);
    Alt = ((LO + 999) / 1000) * 1000;

try this variation

Alt = map(deg, 92, 187, 1, 37) * 1000;