Expm1: примеры (JAVASCRIPT)

Использование Math.expm1 в JavaScript на практике
Раздел: Математика, Экспонента
expm1(number): number

Описание функции Math.expm1

Функция Math.expm1() возвращает результат вычисления выражения ex - 1, где e — число Эйлера (приблизительно 2.718), а x — переданный аргумент. Это статический метод объекта Math.

Основное применение функции связано с повышением точности вычислений при очень малых значениях аргумента x. При прямом вычислении Math.exp(x) - 1 для чисел, близких к нулю, может происходить потеря точности (катастрофическая отмена). Math.expm1() предоставляет результат с более высокой точностью в таких сценариях.

Функция принимает один обязательный аргумент:

  • x: число. Аргумент, который является степенью для числа e в выражении ex - 1.

Возвращаемое значение:

  • Число, представляющее ex - 1.
  • Если аргумент не является числом, он будет неявно преобразован в число. Для нечисловых строк, которые не преобразуются в число (например, 'abc'), возвращается NaN.
  • Для -Infinity возвращается -1.
  • Для Infinity возвращается Infinity.

Базовые примеры использования

Примеры с различными типами аргументов.

console.log(Math.expm1(0));
// Аргумент равен 0: e^0 - 1 = 1 - 1
0
console.log(Math.expm1(1));
// e^1 - 1
1.718281828459045
console.log(Math.expm1(-1));
// e^{-1} - 1
-0.6321205588285577
console.log(Math.expm1(0.000001));
// Малое положительное число
0.0000010000005000001667
console.log(Math.expm1(Infinity));
// Бесконечность
Infinity
console.log(Math.expm1(-Infinity));
-1
console.log(Math.expm1('2')); // Строка преобразуется
6.38905609893065
console.log(Math.expm1(NaN));
NaN

Похожие функции в JavaScript

Math.exp(x): возвращает ex. Является базовой функцией. Для получения результата expm1 можно вычислить Math.exp(x) - 1, но это приводит к потере точности при малых |x|.

Math.log1p(x): вычисляет натуральный логарифм от 1 + x (ln(1+x)). Это обратная операция к Math.expm1(). Используется для аналогичного повышения точности при логарифмировании чисел, близких к 1.

Выбор функции: Math.expm1() предпочтительнее использовать вместо комбинации Math.exp(x) - 1, когда x близко к нулю (например, |x| < 1e-6). В остальных случаях разница в результатах незначительна.

Аналоги функции в других языках

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

Python (math.expm1):

import math
print(math.expm1(0.001))
# 0.0010005001667083847
0.0010005001667083847

PHP (expm1):

echo expm1(0.001);
// 0.0010005001667084
0.0010005001667084

C/C++ (expm1 из math.h):

#include 
#include 
int main() {
    printf("%f\n", expm1(0.001));
    return 0;
}
// 0.001001
0.001001

MySQL (EXP() - 1): Специальной функции нет, используется выражение.

SELECT EXP(0.001) - 1;
-- 0.0010005001667083847
0.0010005001667083847

Семантика и цель использования этих функций идентичны реализации в JavaScript.

Типичные ошибки

1. Ожидание строкового результата или неправильная обработка нечисловых аргументов.

console.log(Math.expm1('abc')); // Нечисловая строка
NaN

2. Непонимание области точности. Для больших аргументов разницы между Math.expm1(x) и Math.exp(x) - 1 нет.

let x = 10;
console.log(Math.expm1(x) === Math.exp(x) - 1);
// Для больших x разницы нет, но стоит учитывать точность сравнения
true

3. Попытка использовать функцию без указания объекта Math.

// let result = expm1(0.1); // ReferenceError: expm1 is not defined
// Правильно:
let result = Math.expm1(0.1);

Изменения в последних версиях

Функция Math.expm1 была добавлена в спецификацию ECMAScript 2015 (ES6). В более ранних версиях JavaScript стандартной реализации не существовало.

С момента добавления в ES6 поведение функции и ее сигнатура не изменялись. Она является частью стандартной библиотеки и поддерживается во всех современных браузерах и средах выполнения, таких как Node.js.

Для обеспечения обратной совместимости со старыми средами можно использовать полифил, который проверяет наличие функции и при необходимости создает ее приближенную реализацию на основе Math.exp.

Расширенные примеры

Пример 1: Вычисление гиперболического синуса с использованием expm1 для повышения точности при малых x.

Пример javascript
function sinhPrecise(x) {
    // sinh(x) = (e^x - e^{-x}) / 2 = (expm1(x) - expm1(-x)) / 2
    if (Math.abs(x) < 1e-8) {
        // Для очень малых x можно использовать разложение в ряд Тейлора
        return x;
    }
    return (Math.expm1(x) - Math.expm1(-x)) / 2;
}
console.log(sinhPrecise(0.0001));
console.log(Math.sinh(0.0001)); // Встроенная функция для сравнения
0.00010000000000166667
0.00010000000000166667

Пример 2: Вычисление относительного изменения с высокой точностью. Например, в финансовых расчетах при очень малых процентных ставках.

Пример javascript
// Модель непрерывного начисления процентов: final = initial * e^{rate*time}
// Относительный прирост: (final - initial) / initial = e^{rate*time} - 1
function continuousGrowthFactor(rate, time) {
    return Math.expm1(rate * time);
}
let tinyRate = 0.00001; // 0.001%
let period = 1;
console.log(continuousGrowthFactor(tinyRate, period));
// Сравним с простым вычислением
console.log(Math.exp(tinyRate * period) - 1);
0.000010000050000166668
0.000010000050000166668

Пример 3: Реализация функции log1p через expm1 (для демонстрации обратной связи).

Пример javascript
function myLog1p(x) {
    // y = ln(1+x) => 1+x = e^y => x = e^y - 1
    // Для нахождения y можно использовать итерационные методы, но это демонстрация связи.
    // На практике для вычисления log1p используются другие алгоритмы.
    // Данный пример только показывает математическую связь.
    let y = Math.log(1 + x); // Базовая версия
    // Проверка: expm1(y) должно быть близко к x
    console.log(`x=${x}, expm1(log1p(x))=${Math.expm1(y)}`);
    return y;
}
myLog1p(0.0005);
x=0.0005, expm1(log1p(x))=0.0005000000000000555

Пример 4: Использование в статистике для вычисления функции распределения с малыми параметрами.

Пример javascript
// Приближенное вычисление функции распределения экспоненциального закона
// F(x; λ) = 1 - e^{-λx} для x >= 0.
// Для малых λx: 1 - e^{-λx} = -expm1(-λx)
function exponentialCDF(x, lambda) {
    if (x < 0) return 0;
    return -Math.expm1(-lambda * x);
}
console.log(exponentialCDF(0.1, 0.01)); // Малое произведение
0.0009995001666250084

JS expm1 function comments

En
Expm1 Returns `e` raised to the power of a number minus 1