简体   繁体   中英

Round to (1, 2, or 5) x 10^n in Objective-C?

Is there a simple way of rounding a value either down to or to the nearest (1, 2, or 5) x 10^n where n is an integer? As in one of {..., .05 .1, .2, .5, 1, 2, 5, 10, 20, 50, 100...}

Thanks.

You can take the d=floor(log10(n)) of your number n to get the scale, then divide by 10 to the d to normalize the number to the range of [1.0,10.0) . From that point it should be easy to round because there are very limited possibilities. Once you've done that, multiply by 10 to the d to restore the number to the original range.

The following function is in C, I don't know enough about Objective-C to know if this is idiomatic.

double RoundTo125(double value)
{
   double magnitude;
   magnitude = floor(log10(value));
   value /= pow(10.0, magnitude);
   if (value < 1.5)
      value = 1.0;
   else if (value < 3.5)
      value = 2.0;
   else if (value < 7.5)
      value = 5.0;
   else
      value = 10.0;
   value *= pow(10.0, magnitude);
   return value;
}

To round x down to the nearest value of c * 10^n , use

f(c) = c * 10^(floor(log(x/c)))

(assuming x is positive). So to round down to the nearest any of those, just find

max(f(1), f(2), f(5))

To round x up to the nearest value of c * 10^n , use

g(c) = c * 10^(ceiling(log(x/c)))

(again assuming x is positive). So to round up to the nearest of any of those, just find

min(g(1), g(2), g(5))

Now to simply round to the nearest of any of those values, find the nearest rounding down (first paragraph) and the nearest rounding up (second paragraph), and choose whichever is closer to x .

As I see you work with numbers with floating point. I want to point you that in standard C library there are two functions that can help you:

double floor(double); //round down
double ceil(double);  //round up

They return rounded number. Also there are another rounding functions. You can find reference of them here . After you learn how they work, you may write your own rounding function. Which will use normalization. Look at example:

// this function will round to tens
float my_floor(float d)
{
    return floor(d/10)*10;
}

The logarithm approach will work, but I would experiment with string conversion. I don't know Objective C, although Google implies you want something called stringWithFormat . In Java, the code would be

String s = String.format("%f", theNumber);
StringBuffer buf = new StringBuffer(s);
int len = buf.length()-1;
char c = buf.getCharAt(len);
switch (c)
{
case '9': case '8': case '7': case '6':
buf.setCharAt(len) = '5'; break;
case '4' : case '3':
buf.setCharAt(len) = '2' break;
default: break; /* don't change '0', '1', '2', '5' */
}
double roundNumber = Double.parseDouble(buf.toString());

Might be faster. (Might be slower!) You could also try searching the string for the decimal point and subtracting an increment from the original number once you new the magnitude of the last decimal place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM