Принятый ответ Марка Рэнсома в основном правильный.
Внедрив это в Java, я нашел еще несколько областей, которые необходимо решить:
- Отрицательные числа должны обрабатываться специально, если вы хотите, чтобы -375 давал -1000
- Потолок для положительных логарифмов, пол + 1 для отрицательных логарифмов (плюс очень важно, если вы хотите, чтобы 0,456 давало 1).
Вот моя реализация на Java с прохождением модульных тестов
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);
}