La risposta accettata da Mark Ransom è per lo più corretta. Dopo aver implementato questo in Java ho trovato alcune altre aree che devono essere affrontate:
- numeri negativi devono essere maneggiati specialmente se si vuole -375 a cedere -1000
- soffitto per i valori di registro positivi, piano + 1 per i valori di log negativi (il più positivo è importante se si desidera che 0.456 restituisca 1).
Qui è la mia implementazione in Java con l'unità di far passare i test
static double roundUpToNearestMagnitude(double n) {
if (n == 0d) return 1d;
boolean negative = n < 0;
double log = Math.log10(Math.abs(n));
double decimalPlaces = ((log > 0)) ? (Math.ceil(log)) : (Math.floor(log) + 1);
double rounded = Math.pow(10, decimalPlaces);
return negative ? -rounded : rounded;
}
@Test public void roundUpToNearestMagnitudeFifty() {
Assert.assertEquals(100d, roundUpToNearestMagnitude(50d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeFive() {
Assert.assertEquals(10d, roundUpToNearestMagnitude(5d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeZeroPointFive() {
Assert.assertEquals(1d, roundUpToNearestMagnitude(0.5d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeZeroPointZeroFive() {
Assert.assertEquals(.1d, roundUpToNearestMagnitude(0.05d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeZeroPointZeroZeroFive() {
Assert.assertEquals(.01d, roundUpToNearestMagnitude(0.005d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeNegativeFifty() {
Assert.assertEquals(-100d, roundUpToNearestMagnitude(-50d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeNegativeFive() {
Assert.assertEquals(-10d, roundUpToNearestMagnitude(-5d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeNegativeZeroPointFive() {
Assert.assertEquals(-1d, roundUpToNearestMagnitude(-0.5d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeNegativeZeroPointZeroFive() {
Assert.assertEquals(-.1d, roundUpToNearestMagnitude(-0.05d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeNegativeZeroPointZeroZeroFive() {
Assert.assertEquals(-.01d, roundUpToNearestMagnitude(-0.005d), 0.000001);
}
@Test public void roundUpToNearestMagnitudeZero() {
Assert.assertEquals(1, roundUpToNearestMagnitude(0d), 0.000001);
}
fonte
2012-02-09 02:51:16
che non è arrotondamento, ma qualcos'altro. È possibile arrotondare 32 a 30 e di conseguenza 30 a 0, ma non a 10 o 1. –