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.
精彩评论