Основы чисел с плавающей точкой
Числа с плавающей точкой полезны для представления нецелых чисел. Диапазон чисел с плавающей точкой совпадает с диапазоном типа данных C double на используемой вами машине. Почти на всех компьютерах, поддерживаемых Emacs, это двоичный формат с плавающей точкой IEEE binary64, стандартизированный в IEEE Std 754-2019 и подробно рассмотренный в статье Дэвида Голдберга «Что должен знать каждый специалист по информатике об арифметике с плавающей точкой». На современных платформах операции с плавающей точкой в значительной степени соответствуют стандарту IEEE-754; однако в некоторых системах, в частности на 32-разрядной архитектуре x86, результаты не всегда округляются правильно.
На некоторых старых компьютерных системах Emacs может не использовать числа с плавающей точкой IEEE. Нам известна одна такая система, на которой Emacs работает правильно, но не соответствует IEEE-754: VAX под управлением NetBSD с GCC 10.4.0, где вместо этого используется формат VAX ‘D_Floating’. Мэйнфреймы на основе IBM System/370 и их компилятор XL/C также могут использовать шестнадцатеричный формат с плавающей точкой, однако Emacs пока не собирали в такой конфигурации.
Синтаксис чтения чисел с плавающей точкой требует наличия десятичной точки, экспоненты или и того, и другого. Перед числом и его экспонентой могут стоять знаки (‘+’ или ‘-’). Например, ‘1500.0’, ‘+15e2’, ‘15.0e+2’, ‘+1500000e-3’ и ‘.15e4’ — это пять способов записать число с плавающей точкой, значение которого равно 1500. Все они эквивалентны. Как и Common Lisp, Emacs Lisp требует наличия хотя бы одной цифры после десятичной точки в числе с плавающей точкой без экспоненты; ‘1500.’ — это целое число, а не число с плавающей точкой.
В числовых сравнениях, таких как =, Emacs Lisp считает -0.0 численно равным обычному нулю. Это соответствует стандарту чисел с плавающей точкой IEEE, согласно которому -0.0 и 0.0 численно равны, хотя другие операции могут их различать.
Стандарт чисел с плавающей точкой IEEE поддерживает положительную и отрицательную бесконечность в качестве значений с плавающей точкой. Он также определяет класс значений NaN, или «не число»; числовые функции возвращают такие значения, когда правильного ответа не существует. Например, (/ 0.0 0.0) возвращает NaN. Значение NaN никогда не равно численно никакому значению, даже самому себе. Значения NaN имеют знак и мантиссу, а нечисловые функции считают два значения NaN равными, если их знаки и мантиссы совпадают. Мантиссы NaN зависят от машины, как и цифры в их строковом представлении.
Если задействованы NaN и знаковые нули, нечисловые функции, такие как eql, equal, sxhash-eql, sxhash-equal и gethash, определяют, неразличимы ли значения, а не равны ли они численно. Например, если x и y — одно и то же значение NaN, (equal x y) возвращает t, тогда как (= x y) использует числовое сравнение и возвращает nil; наоборот, (equal 0.0 -0.0) возвращает nil, тогда как (= 0.0 -0.0) возвращает t.
Ниже приведены синтаксические формы чтения этих специальных значений с плавающей точкой:
- бесконечность
‘1.0e+INF’ и ‘-1.0e+INF’
- не число
‘0.0e+NaN’ и ‘-0.0e+NaN’
Бесконечности и NaN недоступны в устаревших системах, не поддерживающих арифметику с плавающей точкой IEEE. Например, на VAX примерно 1980 года Lisp считывает ‘1.0e+INF’ как большое, но конечное число с плавающей точкой, а ‘0.0e+NaN’ — как другой нечисловой объект Lisp, использование которого в числовых операциях вызывает ошибку.
Для обработки чисел с плавающей точкой предназначены следующие функции:
- Функция: isnan x
Этот предикат возвращает
t, если его аргумент с плавающей точкой является NaN, иnilв противном случае.
- Функция: frexp x
-
Эта функция возвращает конс-ячейку
(s . e), где s и e — соответственно мантисса и экспонента числа с плавающей точкой x.Если x конечно, то s — число с плавающей точкой от 0.5 (включительно) до 1.0 (не включительно), e — целое число, а x = s * 2**e. Если x равно нулю или бесконечности, то s совпадает с x. Если x — NaN, то s также является NaN. Если x равно нулю, то e равно 0.
- Функция: ldexp s e
Получив числовую мантиссу s и целочисленную экспоненту e, эта функция возвращает число с плавающей точкой s * 2**e.
- Функция: copysign x1 x2
Эта функция копирует знак x2 в значение x1 и возвращает результат. x1 и x2 должны быть числами с плавающей точкой.
- Функция: logb x
-
Эта функция возвращает двоичную экспоненту x. Точнее, если x конечно и не равно нулю, результатом будет логарифм по основанию 2 от |x|, округлённый вниз до целого числа. Если x равно нулю или бесконечности, результатом будет бесконечность; если x — NaN, результатом будет NaN.
(logb 10) ⇒ 3 (logb 10.0e20) ⇒ 69 (logb 0) ⇒ -1.0e+INF
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Float-Basics.html