Przyjęta odpowiedź Marka Ransoma jest w większości poprawna. Po wdrożone w Java Znalazłem jeszcze kilka obszarów, które należy rozwiązać:
- Ujemne numery muszą być traktowane specjalnie, jeśli chcesz -375 uzyskując -1000
- sufitowe dla wartości dodatnich dziennika, podłoga + 1 dla ujemnych wartości logów (plus jeden jest ważny, jeśli chcesz 0.456, aby uzyskać 1).
Oto moja implementacja w języku Java z jednostki przeszły badania
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);
}
To nie zaokrąglania, ale coś innego. Możesz zaokrąglić 32 do 30, a co za tym idzie 30 do 0, ale nie do 10 lub 1. –