Глаза страшат, а руки делают

ЧАСТЬ ВТОРАЯ


26. Объект Math

  • предопределённые константы — свойства;
  • методы;
  • примеры;
  • баги;
  • функция извлечения любых корней.

До сих пор мы встречались с объектами, имеющими свои экземпляры. В основном мы пользовались экземплярами, но иногда создавали новые объекты с помощью конструктора. Также нам знакомо понятие «статический метод» — то есть метод, который обращается к самому объекту, а не его экземпляру.

У объекта Math не бывает экземпляров.

К нему неприменима функция конструктора.

Все его методы и свойства — статические.

Объект Math используется как библиотека математических констант и операций (главным образом тригонометрических). Вызов свойств или методов объекта Math твердо придерживается следующего синтаксиса:

Math.свойство;
Math.метод(аргументы);

(Как мы помним, все имена встроенных объектов пишутся с большой буквы.)

Предопределённые константы (свойства)

В JavaScript нет специального объекта «константа», как в других языках ООП. Данные константы, содержащие определённые числовые значения, по сути дела являются свойствами объекта Math.

Перечислим их:

Константа (свойство)

Описание

Значение*

Синтаксис

E

Константа Эйлера (число e)

2.718

 Math.E;

LN10

Натуральный логарифм десяти (loge10)

2.302

 Math.LN10;

LN2

Натуральный логарифм двух (loge2)

0.693

 Math.LN2;

LOG10E

Логарифм числа e по основанию 10 (log10e)

0.434

 Math.LOG10E;

LOG2E

Логарифм числа e по основанию 2 (log2e)

1.442

 Math.LOG2E;

PI

Отношение длины окружности к её диаметру (число π)

3.14159

 Math.PI;

SQRT1_2

Корень квадратный из 1/2

0.707

 Math.SQRT1_2;

SQRT2

Корень квадратный из 2

1.414

 Math.SQRT2;

*Поскольку это вещественные (действительные) иррациональные числа, их значения являются приблизительными.

Методы

Примечание

Все величины углов задаются и возвращаются в радианах.

Конверсия между градусами и радианами:

α[рад] = (π / 180) × α[°]

α[°] = (180 / π) × α[рад]

abs

Возвращает абсолютную величину числа или арифметического выражения.

Math.abs(число)

acos

Возвращает арккосинус (в радианах) числа или арифметического выражения в пределах от -1 до 1.

Math.acos(число)

asin

Возвращает арксинус (в радианах) числа или арифметического выражения в пределах от -1 до 1.

Math.asin(число)

atan

Возвращает арктангенс (в радианах) числа или арифметического выражения в пределах от -1 до 1.

Math.atan(число)

atan2

Возвращает арктангенс угла, образованного положительной полуосью OX и лучом, проходящим через точки (0, 0) и (x, y). Результат находится в диапазоне от -π до +π и соответствует величине угла в радианах между осью абсцисс и вектором до точки с координатами (x, y). Использует два аргумента.

Math.atan2(x, y)

Аргументы:

x, y — числа или арифметические выражения, представляющие собой соответственно X- и Y- координаты точки.

ceil

Возвращает наименьшее целое число, большее или равное данному числу или арифметическому выражению.

Math.ceil(число)

cos

Возвращает косинус числа или арифметического выражения (аргумент задаётся в радианах).

Math.cos(число)

exp

Возвращает Enum, где num — аргумент (число или арифметическое выражение), а E — константа Эйлера (число e).

Math.exp(число)

floor

Возвращает набольшее целое число, меньшее или равное данному числу или арифметическому выражению.

Math.floor(число)

log

Возвращает натуральный логарифм числа или арифметического выражения.

Math.log(число)

max

Возвращает максимальное из двух чисел (аргументы x, y).

Math.max(x, y)

min

Возвращает минимальное из двух чисел (аргументы x, y).

Math.min(x, y)

pow

Использует два аргумента, возвращает аргумент1аргумент2

Math.pow(x, y)

random

Возвращает дробное число, равномерно распределённое в интервале от 0 до 1. Аргументов не имеет.

Math.random()

Примечание:

Чтобы получить случайное целое число между нулём и другим максимальным значением, используйте следующую формулу:

Math.round(Math.random() * n)

(n — верхнее целое число приемлемого диапазона.)

Чтобы получить случайное любое число между нулём и другим максимальным значением, используйте следующую формулу:

Math.random() * n

(n — верхнее число приемлемого диапазона.)

Чтобы получить случайное целое число между единицей и другим максимальным значением, используйте следующую формулу:

Math.floor(Math.random() * (-n)) % (-n) + n

(n — верхнее целое число приемлемого диапазона.)

Чтобы получить случайное целое число в диапазоне, начинающемся с номера, отличного от нуля, используйте следующую формулу:

Math.round(Math.random() * n) + m

(m — самое низкое целое число приемлемого диапазона, n + m — верхнее число диапазона.) То есть, чтобы получить рэндом от 7 до 25, надо записать:

Math.round(Math.random() * 18) + 7

Чтобы получить случайное любое число в диапазоне, начинающемся с номера, отличного от нуля, используйте следующую формулу:

Math.random() * n + m

(m — самое низкое число приемлемого диапазона, n + m — верхнее число диапазона.)

round

Округляет аргумент с плавающей точкой до ближайшего большего целого числа, если десятичная часть больше или равна 0,5, или до ближайшего меньшего целого числа, если десятичная часть меньше, чем 0,5.

Math.round(дробное_число)

sin

Возвращает синус числа или арифметического выражения (аргумент задаётся в радианах).

Math.sin(число)

sqrt

Возвращает квадратный корень числа или арифметического выражения.

Math.sqrt(число)

tan

Возвращает тангенс числа или арифметического выражения (аргумент задаётся в радианах).

Math.tan(число)

Некоторые примеры с использованием объекта Math

Как я уже отметил, все углы объект Math использует в радианах. А нам как-то привычнее в градусах. Я привёл формулы пересчёта в алгебраическом выражении. Давайте теперь сделаем из них маленькие функции.

Градусы в радианы

function isRad(deg) {
    var result = Math.PI / 180 * deg;
    return result;
}

Радианы в градусы

function isDeg(rad) {
    var result = 180 / Math.PI * rad;
    return result;
}

А теперь немножко поиграем с рэндомом.

Сначала «в чепуху».

Предположим, у нас есть два массива:

var nouns = ["кошка", "собака", "ворона", "петух", "волк"];
var verbs = ["мяукает", "лает", "каркает", "кукарекает", "воет"];

Рэндомизируем каждый массив по отдельности:

var myTxt1 = nouns[Math.round(Math.random() * (nouns.length-1))];
var myTxt2 = verbs[Math.round(Math.random() * (verbs.length-1))];

Теперь составим фразу:

var phrase = myTxt1 + " " + myTxt2;

И запакуем всё это в функцию для попеременного вывода:

function showTotalRandom(place) {
var myTxt1 = nouns[Math.round(Math.random() * (nouns.length-1))];
var myTxt2 = verbs[Math.round(Math.random() * (verbs.length-1))];
var phrase = myTxt1 + " " + myTxt2;
document.getElementById(place).innerHTML = phrase;
}

var start = setInterval("showTotalRandom('writeTxt')", 750);

И место для вывода:

<p id="writeTxt"></p>

Итак:

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

function showOrderedRandom(place) {
var rnd = Math.round(Math.random() * 4)
var myTxt1 = nouns
var myTxt2 = verbs
var phrase = myTxt1[rnd] + " " + myTxt2[rnd]
document.getElementById(place).innerHTML = phrase;
}

var pusk = setInterval("showOrderedRandom('writeTxt2')", 750);

Делаем второй абзац:

<p id="writeTxt2"></p>

Проверяем:

Эти идеи можно положить в основу тестов, где вопросы, выпадающие хаотично, должны «тянуть» за собой упорядоченные наборы ответов.

«Тараканы»

Попробуйте какое-нибудь десятичное число, оканчивающееся на 15 сотых, умножить, скажем, на 3 или на 6:

var a = 0.15, b = 3, c = a * b;
document.write(a + " &times; " + b + " = " + c);

Выполним.

Получим:

Есть такой стандарт IEEE-54, в котором JavaScript представляет вещественные числа в виде 64-разрядных беззнаковых величин с плавающей точкой. Здесь и сидят тараканы.

Помните, в прошлом уроке была функция для вычисления площади и объёма? Давайте немного её подточим и сделаем функцию для правильного умножения.

Во-первых, уберём ограничение на 3 аргумента, а во-вторых...

Смотрите сами:

function correctMultiple() {
/* инициализируем исходную переменную не как единицу, а как 100 */
var i, res = 100, correct, err;
    for (i=0; i<arguments.length; i++)
    {res = res * arguments[i]}
    /* а теперь делим результат обратно */
    correct = res / 100;
        /* если ввели не число, а, например, матерное слово */
        if (isNaN(res))
            {err = "Неверные данные";
            return err;}
        else
            /* Если ввели только одно число или ничего не ввели */
            {if (arguments.length < 2)
                {err = "Недостаточно данных";
                return err;}
            else
                return correct;}
}

Примечание

isNaN — это одна из так называемых функций ядра, о которых будет сказано несколькими уроками позже.

Протестируем:

document.write(a + " &times; " + b + " = " + correctMultiple(a, b))

Результат:

Функция извлечения корня любой степени

В этой функции мы поставим две задачи.

Первая — извлечение корня с помощью комбинации методов объекта Math.

Вторая — округление до нескольких десятичных знаков.

Как вы уже заметили, среди готовых методов есть только округление до целых чисел. Эта проблема легко решается с помощью одного из методов объекта Number, о котором речь пойдёт чуть дальше. Сегодня же мы потренируем мозги и сделаем это «домашними» средствами. Пригодится нам тут и «выведение тараканов IEEE-54» с помощью умножения/деления.

Основа следующая. При извлечении корня степени y из числа x нужно получить экспоненту результата деления натурального логарифма x на y. Да, по-русски это как-то заумно и коряво звучит, а формула на самом деле очень простая и прозрачная:

Math.exp(Math.log(x) / y);

Описание механизма функции

(результат будет выведен в виде строки, округление до 3 знаков)

1. Выполняем извлечение корня по только что приведённой формуле.

2. Конвертируем значение в строку, с которой начинаем работать.

3. Выясняем, на какой позиции в строке находится точка.

4. Если эта позиция меньше 1 (на нулевой позиции точки не бывает — значит, это целое число), выводим результат без последующей обработки.

5. В противном случае отсекаем подстроку с 4 символами после точки (чтобы правильно округлить до 3 знаков, нужно знать четвёртый).

6. Исследуем последний символ. Если его числовое значение меньше 5, сокращаем строку на 1 символ, конвертируем в число, умножаем на 1000 и делим на 1000. Конвертируем обратно в строку и передаём результат как возвращаемое значение.

7. В противном случае после умножения на 1000 прибавляем единицу, делим-конвертируем-возвращаем.

Запись кода

function anyRoot(x, y) {
/* объявление и назначение переменных */
var cut1, cut2, result;
var initialString = "" + Math.exp(Math.log(x) / y);
var dot = initialString.lastIndexOf(".");
...

cut1 — обрезка до 4 знаков, cut2 — обрезка до 3 знаков, result — переменная для возвращаемого значения.

initialString: выражение "" + число создаёт строковое выражение числа.

dot — возвращает позицию точки в строке.

Едем дальше.

...
if (dot < 1)
result = initialString;
else {
    cut1 = initialString.substring(0, dot+5);
    if (Number(cut1.substr(cut1.length - 1, 1)) < 5)
        {cut2 = Number(cut1.substr(0, cut1.length - 1))*1000 / 1000;
        result = cut2.toString(10);}
    else
        {cut2 = (Number(cut1.substr(0, cut1.length - 1))*1000 + 1) / 1000;
        result = cut2.toString(10);}
    }
return result;
}

Проверить работу функции удобно через формы ввода текста:

<form>
<input type=
"text" id="one">&nbsp;&nbsp;<input type="text" id="two"><br>
<input type="text" id="three">&nbsp;&nbsp;
<input type="button" value="сосчитать" onClick="getElementById('three').value=anyRoot(getElementById('one').value, getElementById('two').value);">
</form>
    
  

Домашние задания

1. Вставьте в последнюю функцию «защиту от дурака» (в виде вывода сообщений)

    а). когда одно или оба поля не заполнены;

    б). когда в одно или оба поля введены нечисловые символы.

2. Добавьте для этих же полей ввода опцию возведения в степень. Это можно сделать как расширением текущей функции, так и созданием новой. Потребуется также добавить «радио-кнопки» для переключения опций и изменить событие onClick для выполняющей кнопки.


Итак, мы узнали:

что можно делать с объектом Math.

А также научились:

умножать без таракнов.


К следующему уроку >>


 008028