Сокращённая арифметика с присваиванием — КиберПедия 

Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...

Сокращённая арифметика с присваиванием

2020-05-07 175
Сокращённая арифметика с присваиванием 0.00 из 5.00 0 оценок
Заказать работу

Часто в коде нужно применить оператор к переменной и сохранить результат в ней же, например:

var n = 2;

n = n + 5;

n = n * 2;

Эту запись можно укоротить при помощи совмещённых операторов, вот так:

var n = 2;

n += 5; // теперь n=7 (работает как n = n + 5)

n *= 2; // теперь n=14 (работает как n = n * 2)

alert(n); // 14

Так можно сделать для операторов +, -, *, /, % и бинарных <<, >>, >>>, &, |, ^ (о них немного позже).

Вызов с присваиванием имеет в точности такой же приоритет, как обычное присваивание, то есть выполнится после большинства других операций:

var n = 2;

n *= 3 + 5;

alert(n); // 16 (n = 2 * 8)

Инкремент/декремент: ++, --

Одной из частых операций в JavaScript, как и во многих других языках, является увеличение или уменьшение переменной на единицу. Чаще всего это используется в конструкции цикла.

Разработчики JS придумали для этих целей специальный оператор:

Инкремент ++ увеличивает на 1:

var i = 2;

i++; // более короткая запись для i = i + 1.

alert(i); // 3

Декремент -- уменьшает на 1:

var i = 2;

i--; // более короткая запись для i = i - 1.

alert(i); // 1

Важно!

Инкремент/декремент можно применить только к переменной. Код 5++ даст ошибку.

Вызывать эти операторы можно не только после, но и перед переменной: i++ (называется «постфиксная форма») или ++i («префиксная форма»).

Обе эти формы записи делают одно и то же: увеличивают на 1, но между ними существует разница. Она видна только в том случае, когда мы хотим не только увеличить/уменьшить переменную, но и использовать результат в том же выражении.

Например:

var i = 1;

var a = ++i;

alert(a); // 2

В этом примере вызов ++i (префиксная форма) увеличит переменную, а затем вернёт ее значение в переменную a. Так что в a попадёт значение i после увеличения.

Постфиксная форма i++ отличается от префиксной ++i тем, что возвращает старое значение, бывшее до увеличения.

В примере ниже в переменную a попадёт старое значение i, равное 1:

var i = 1;

var a = i++;

alert(a); // 1

Если результат оператора не используется, а нужно только увеличить/уменьшить переменную – то тогда без разницы, какую форму использовать:

var i = 0;

i++;

++i;

alert(i); // 2

Если хочется тут же использовать результат, то нужна префиксная форма:

var i = 0;

alert(++i); // 1

Если нужно увеличить, но нужно значение переменной до увеличения – постфиксная форма:

var i = 0;

alert(i++); // 0

Инкремент/декремент можно использовать в любых выражениях, при этом он имеет более высокий приоритет и выполняется раньше, чем арифметические операции.

Сложение строк, бинарный +

Давайте посмотрим возможности операторов JS, которые выходят за рамки школьной математики.

Обычно при помощи плюса ' + ' складывают числа. Но если бинарный оператор '+' применить к строкам, то он их объединяет в одну:

let s = "моя" + "строка";

alert(s); // моястрока

Обратите внимание, если хотя бы один операнд является строкой, то второй будет также преобразован к строке, например:

alert('1' + 2); // "12"

alert(2 + '1'); // "21"

Причём не важно, справа или слева находится операнд-строка. Правило простое: если хотя бы один из операндов является строкой, то второй будет также преобразован к строке.

Тем не менее, помните, что операции выполняются слева направо. Если перед строкой идут два числа, то числа будут сложены перед преобразованием в строку:

alert(2 + 2 + '1'); // будет "41", а не "221"

Сложение и преобразование строк – это особенность бинарного плюса +. Другие арифметические операторы работают только с числами и всегда преобразуют операнды в числа.

Например, вычитание и деление:

alert(2 - '1'); // 1

alert('6' / '2'); // 3

Преобразование к числу, унарный плюс +, и методы

Унарный плюс, то есть применённый к одному значению, ничего не делает с числами с точки зрения арифметических операций. Тем не менее, он широко применяется, так как его «побочный эффект» – это преобразование значения в число.

Например, когда мы получаем значения из HTML-полей или от пользователя, то они обычно в форме строк (это же касается и prompt).

А что, если их нужно, к примеру, сложить? Бинарный плюс сложит их как строки:

var apples = "2";

var oranges = "3";

alert(apples + oranges); // "23", так как бинарный плюс складывает строки

Поэтому используем унарный плюс, чтобы преобразовать к числу:

var apples = "2";

var oranges = "3";

alert(+apples + +oranges); // 5, число, оба операнда предварительно преобразованы в числа

С точки зрения математики такое изобилие плюсов может показаться странным. С точки зрения программирования – никаких разночтений: сначала выполнятся унарные плюсы, они приведут строки к числам, а затем – бинарный '+' их сложит.

Почему унарные плюсы выполнились до бинарного сложения? Все дело в их приоритете, он больше.

Методы преобразование в числа

Существует 3 метода JS, которые можно использовать для преобразования переменных в числа:

1. Метод Number()

2. Метод parseInt()

3. Метод parseFloat()

Метод Number()

Number () используется для преобразования переменных JavaScript в числа, например:

Number(true); // returns 1

Number(false); // returns 0

Number("10"); // returns 10

Number("10 20"); // returns NaN

Number("John"); // returns NaN

Если число не может быть преобразовано, возвращается значение NaN (не число).

Очень часто метод Number(), используется при работе с датами, например:

Number(new Date("2017-09-30")); // returns 1506729600000

Метод Number () возвращает число миллисекунд с момента 1.1.1970.

Метод parseInt()

parseInt() анализирует строку и возвращает целое число.

Пробелы разрешены. Возвращается только первое число, например:

parseInt("10"); // returns 10

parseInt("10.33"); // returns 10

parseInt("10 20 30"); // returns 10

parseInt("10 years"); // returns 10

parseInt("years 10"); // returns NaN

Если число не может быть преобразовано, возвращается значение NaN (не число).

Метод parseFloat()

parseFloat() анализирует строку и может возвращать число с плавающей точкой, а в остальном он похож на метод parseInt(). Пробелы разрешены. Возвращается только первый номер, например:

parseFloat("10.33"); // returns 10.33

parseFloat("years 10.25"); // returns NaN

Если число не может быть преобразовано, возвращается значение NaN (не число).

Числа

Так как мы уже кратко знакомились с числами, мы просто рассмотрим некоторые особенности при работе с ними

Деление на ноль, Infinity

Представьте, что вы собираетесь создать новый язык… Люди будут называть его «JavaScript» (или «LiveScript»… неважно).

Что должно происходить при попытке деления на ноль? Как правило, ошибка в программе… Во всяком случае, в большинстве языков программирования это именно так.

Но создатель JavaScript решил пойти математически правильным путем. Ведь чем меньше делитель, тем больше результат. При делении на очень-очень маленькое число должно получиться очень большое. В математическом анализе это описывается через пределы, и если подразумевать предел, то в качестве результата деления на 0 мы получаем «бесконечность», которая обозначается символом ∞ (в JS - Infinity).

alert(1 / 0); // Infinity

alert(12345 / 0); // Infinity

Infinity – особенное значение, которое ведет себя в точности как математическая бесконечность ∞.

· Infinity больше любого числа.

· Добавление к бесконечности любого числа не меняет её.

alert(Infinity > 1234567890); // true

alert(Infinity + 5 == Infinity); // true

Бесконечность можно присвоить и в явном виде: var x = Infinity.

Бывает и минус бесконечность -Infinity:

alert(-1 / 0); // -Infinity

Бесконечность можно получить также, если сделать ну очень большое число, для которого количество разрядов в двоичном представлении не помещается в соответствующую часть стандартного 64-битного формата, например:

alert(1e500); // Infinity

NaN

Если математическая операция не может быть совершена, то возвращается специальное значение NaN (Not-A-Number).

Например, деление 0/0 в математическом смысле неправильно, поэтому его результат NaN:

alert(0 / 0); // NaN

Значение NaN используется для обозначения математической ошибки и обладает следующими свойствами:

· Значение NaN – единственное в своем роде, которое не равно ничему, включая себя.

· Значение NaN можно проверить специальной функцией isNaN(n), которая преобразует аргумент к числу и возвращает true, если получилось NaN, и false – для другого значения.

var n = 0 / 0;

alert(isNaN(n)); // true

alert(isNaN("12")); // false, строка преобразовалась к обычному числу 12

· Значение NaN «прилипчиво», т.е. любая операция с NaN возвращает NaN.

Неточные вычисления

Запустите этот пример:

alert(0.1 + 0.2 == 0.3);

Запустили? Если нет – все же сделайте это.

Ок, вы запустили его. Он вывел false. Результат несколько странный, не так ли? Возможно, ошибка в браузере? Поменяйте браузер, запустите еще раз.

Хорошо, теперь мы можем быть уверены: 0.1 + 0.2 это не 0.3. Но тогда что же это?

alert(0.1 + 0.2); // 0.30000000000000004

Как видите, произошла вычислительная ошибка, результат 0.1 + 0.2 немного больше, чем 0.3.

alert(0.1 + 0.2 > 0.3); // true

Всё дело в том, что в стандарте IEEE 754 на число выделяется 8 байт (64 бита), не больше и не меньше.

Число 0.1 (одна десятая) записывается просто в десятичном формате. Но в двоичной системе счисления это бесконечная дробь, так как единица на десять в двоичной системе так просто не делится. Также бесконечной дробью является 0.2 (2/10).

Двоичное значение бесконечных дробей хранится только до определенного знака, поэтому возникает неточность. Её даже можно увидеть:

alert(0.1.toFixed(20)); // 0.10000000000000000555

Когда мы складываем 0.1 и 0.2, то две неточности складываются, получаем незначительную, но всё же ошибку в вычислениях. Конечно, это не означает, что точные вычисления для таких чисел невозможны. Они возможны. И даже необходимы. Например, есть два способа сложить 0.1 и 0.2:

1. Сделать их целыми, сложить, а потом поделить:

alert((0.1 * 10 + 0.2 * 10) / 10); // 0.3

Это работает, так как числа 0.1*10 = 1 и 0.2*10 = 2 могут быть точно представлены в двоичной системе.

2. Сложить, а затем округлить до разумного знака после запятой. Округления до 10-го знака обычно бывает достаточно, чтобы отсечь ошибку вычислений:

var result = 0.1 + 0.2;

alert(+result.toFixed(10)); // 0.3

Забавный пример

Привет! Я – число, растущее само по себе!

alert(9999999999999999); // выведет 10000000000000000

Причина та же – потеря точности.

Из 64 бит, отведённых на число, сами цифры числа занимают до 52 бит, остальные 11 бит хранят позицию десятичной точки и один бит – знак. Так что если 52 бит не хватает на цифры, то при записи пропадут младшие разряды.

Интерпретатор не выдаст ошибку, но в результате получится «не совсем то число», что мы и видим в примере выше. Как говорится: «как смог, так записал».

Ради справедливости заметим, что ошибка в точности для чисел с плавающей точкой сохраняется в любом другом языке, где используется формат IEEE 754, включая Java, C, PHP, Ruby, Perl, Python.


Поделиться с друзьями:

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.034 с.