NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Вот тот же код на Java без ошибки 12.100000000000001, есть другие ответы
Я также удалил повторяющийся код, изменил power
на целое число, чтобы предотвратить проблемы с плавающей точкой, когда n - d
сделано, и длинное промежуточное значение стало более понятным
Ошибка была вызвана умножением большого числа на малое. Вместо этого я делю два числа одинакового размера.
РЕДАКТИРОВАТЬ
Исправлено больше ошибок. Добавлена проверка на 0, так как это приведет к NaN. Функция действительно работает с отрицательными числами (исходный код не обрабатывает отрицательные числа, потому что журнал отрицательного числа является комплексным числом)
public static double roundToSignificantFigures(double num, int n) {
if(num == 0) {
return 0;
}
final double d = Math.ceil(Math.log10(num < 0 ? -num: num));
final int power = n - (int) d;
final double magnitude = Math.pow(10, power);
final long shifted = Math.round(num*magnitude);
return shifted/magnitude;
}
СВОДКА:
double roundit(double num, double N)
{
double d = log10(num);
double power;
if (num > 0)
{
d = ceil(d);
power = -(d-N);
}
else
{
d = floor(d);
power = -(d-N);
}
return (int)(num * pow(10.0, power) + 0.5) * pow(10.0, -power);
}
<час> , Таким образом, необходимо найти десятичный разряд первой ненулевой цифры, затем сохраните следующие N-1 цифры, затем вокруг Энной цифры на основе остальных.
Мы можем использовать журнал, чтобы сделать первое.
log 1239451 = 6.09
log 12.1257 = 1.08
log 0.0681 = -1.16
Так для чисел> 0, возьмите перекрытие журнала. Для чисел < 0, получите слово журнала.
Теперь у нас есть цифра d
: 7 в первом случае, 2 в 2-м,-2 в 3-м.
Мы имеем к раунду (d-N)
th цифра. Что-то как:
double roundedrest = num * pow(10, -(d-N));
pow(1239451, -4) = 123.9451
pow(12.1257, 1) = 121.257
pow(0.0681, 4) = 681
Тогда делают стандартную вещь округления:
roundedrest = (int)(roundedrest + 0.5);
И отмена голова.
roundednum = pow(roundedrest, -(power))
, Где питание является питанием, вычисленным выше.
<час>О точности: ответ Pyrolistical действительно ближе к реальному результату. Но обратите внимание, что Вы не можете представить 12.1 точно в любом случае. Если Вы печатаете ответы следующим образом:
System.out.println(new BigDecimal(n));
ответы:
Pyro's: 12.0999999999999996447286321199499070644378662109375
Mine: 12.10000000000000142108547152020037174224853515625
Printing 12.1 directly: 12.0999999999999996447286321199499070644378662109375
Так, используйте ответ Пиротехнического средства!
Вот короткая и сладкая реализация JavaScript:
function sigFigs(n, sig) {
var mult = Math.pow(10, sig - Math.floor(Math.log(n) / Math.LN10) - 1);
return Math.round(n * mult) / mult;
}
alert(sigFigs(1234567, 3)); // Gives 1230000
alert(sigFigs(0.06805, 3)); // Gives 0.0681
alert(sigFigs(5, 3)); // Gives 5
Вы попытались просто кодировать его способ, которым Вы сделали бы это вручную?
Разве это не «короткая и приятная» реализация JavaScript
Number(n).toPrecision(sig)
, например,
alert(Number(12345).toPrecision(3)
?
Извините, Здесь я не шучу, просто использование функции "roundit" из Claudiu и .toPrecision в JavaScript дает мне другие результаты, но только при округлении последней цифры.
JavaScript:
Number(8.14301).toPrecision(4) == 8.143
.NET
roundit(8.14301,4) == 8.144
[Исправлено, 2009-10-26]
По сути, для N значащих дробных цифр:
• Умножьте число на 10 N
• Добавить 0,5
• Усекать дробные цифры (т. Е. Усекать результат до целого числа)
• Разделить на 10 N
Для N значащих целых (недробных) цифр:
• Разделить число на 10 N
• Добавить 0,5
• Усекать дробные цифры (т. Е. Усекать результат до целого числа)
• Умножение на 10 N
Вы можете сделать это на любом калькуляторе, например, который имеет оператор «INT» (целочисленное усечение).
Вот модифицированная версия JavaScript Атеса, которая работает с отрицательными числами.
function sigFigs(n, sig) {
if ( n === 0 )
return 0
var mult = Math.pow(10,
sig - Math.floor(Math.log(n < 0 ? -n: n) / Math.LN10) - 1);
return Math.round(n * mult) / mult;
}
/**
* Set Significant Digits.
* @param value value
* @param digits digits
* @return
*/
public static BigDecimal setSignificantDigits(BigDecimal value, int digits) {
//# Start with the leftmost non-zero digit (e.g. the "1" in 1200, or the "2" in 0.0256).
//# Keep n digits. Replace the rest with zeros.
//# Round up by one if appropriate.
int p = value.precision();
int s = value.scale();
if (p < digits) {
value = value.setScale(s + digits - p); //, RoundingMode.HALF_UP
}
value = value.movePointRight(s).movePointLeft(p - digits).setScale(0, RoundingMode.HALF_UP)
.movePointRight(p - digits).movePointLeft(s);
s = (s > (p - digits)) ? (s - (p - digits)) : 0;
return value.setScale(s);
}
Как насчет этого решения Java:
double roundToSignificantFigure(double num, int precision){ return new BigDecimal(num) .round(new MathContext(precision, RoundingMode.HALF_EVEN)) .doubleValue(); }