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 - 10
console.log(Math.expm1(1));
// e^1 - 11.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.00100050016670838470.0010005001667083847
PHP (expm1):
echo expm1(0.001);
// 0.00100050016670840.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.00100050016670838470.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.
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: Вычисление относительного изменения с высокой точностью. Например, в финансовых расчетах при очень малых процентных ставках.
// Модель непрерывного начисления процентов: 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 (для демонстрации обратной связи).
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: Использование в статистике для вычисления функции распределения с малыми параметрами.
// Приближенное вычисление функции распределения экспоненциального закона
// 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