I'm writing an application which requires rounding labels to the nearest 'nice' number. I'll put some code below to demonstrate this, but my issue is that I was using a series of else ifs to find this number but I cannot be sure of the upper limit so this isn't really a good strategy. Are there any known algorithms or resources which could help me?
if (diff <= 1) {
roundAmount = 0.2;
} else if (diff <= 5) {
roundAmount = 1;
} else if (diff <= 10) {
roundAmount = 2;
} else if (diff <= 25) {
roundAmount = 5;
} else if (diff <= 50) {
roundAmount = 10;
} else if (diff <= 100) {
roundAmount = 20;
} else if (diff <= 250) {
roundAmount = 50;
} else if (diff <= 500) {
roundAmount = 100;
} else if (diff <= 1000){
roundAmount = 200;
} etc...
int test = 5 * (value / 5); for the next value (step 5) above, just add 5. Be careful here. If value is int, it always rounds down.
If the number you are rounding is followed by 5, 6, 7, 8, or 9, round the number up. Example: 38 rounded to the nearest ten is 40. If the number you are rounding is followed by 0, 1, 2, 3, or 4, round the number down. Example: 33 rounded to the nearest ten is 30.
Rounding is a process to estimate a particular number in a context. To round a number look at the next digit in the right place, if the digit is less than 5, round down and if the digit is 5 or more than 5, round up. Rounding decimals refer to the rounding of decimal numbers to a certain degree of accuracy.
In C#, Math. Round() is a Math class method which is used to round a value to the nearest integer or to the particular number of fractional digits. This method has another overload with which, you can specify the number of digits beyond the decimal point in the returned value.
You can use Math.log10
to normalize all values before doing your "nice number" search, something like this:
[Edit] I just realized you are using Java instead of C#, so I modified the code a bit. I don't have a compiler around to test it, but you should get the general idea anyway:
static double getNicerNumber(double val)
{
// get the first larger power of 10
var nice = Math.pow(10, Math.ceiling(Math.log10(val)));
// scale the power to a "nice enough" value
if (val < 0.25 * nice)
nice = 0.25 * nice;
else if (val < 0.5 * nice)
nice = 0.5 * nice;
return nice;
}
// test program:
static void main(string[] args)
{
double[] values =
{
0.1, 0.2, 0.7,
1, 2, 9,
25, 58, 99,
158, 267, 832
};
for (var val : values)
System.out.printf("$%.2f --> $%.2f%n", val, getNicerNumber(val));
}
This will print something like:
0,1 --> 0,1 0,2 --> 0,25 0,7 --> 1 1 --> 1 2 --> 2,5 9 --> 10 25 --> 50 58 --> 100 99 --> 100 158 --> 250 267 --> 500 832 --> 1000
I prefer the following over Groo's approach, as it rounds 267 to 275 instead of 500. It basically rounds to the first digit, and then the nearest quarter fraction of that power of 10.
static double round_pretty(double val) {
var fraction = 1;
var log = Math.floor(Math.log10(val));
// This keeps from adding digits after the decimal
if(log > 1) {
fraction = 4;
}
return Math.round(val * fraction * Math.pow(10, -log))
/ fraction / Math.pow(10, -log);
}
The output is as follows:
0.01 -> 0.01
0.025 -> 0.03 (Groo's does 0.025)
0.1 -> 0.1
0.2 -> 0.2 (Groo's does 0.25)
0.49 -> 0.5
0.5 -> 0.5 (Groo's does 1)
0.51 -> 0.5 (Groo's does 1)
0.7 -> 0.7 (Groo's does 1)
1 -> 1
2 -> 2 (Groo's does 2.5)
9 -> 9
23.07 -> 20
25 -> 30
49 -> 50
50 -> 50 (Groo's does 100 here)
58 -> 60
94 -> 90
95 -> 100
99 -> 100
100 -> 100
109 -> 100 (Groo's does 250 here)
158 -> 150
249 -> 250
267 -> 275
832 -> 825
1234567 -> 1250000
1499999 -> 1500000
1625000 -> 1750000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With