Rust: Добавить поддержку шестнадцатеричных литералов с плавающей запятой

Созданный на 5 янв. 2012  ·  17Комментарии  ·  Источник: rust-lang/rust

Нам нужно иметь возможность анализировать вывод printf% a для правильной поддержки математических констант без потери точности.
(т.е. синтаксис 0x1.fffffffffffffp + 1023_f64)

A-frontend E-easy

Самый полезный комментарий

Шестнадцатеричные числа с плавающей запятой довольно популярны среди математических библиотек C. И я бы также хотел использовать их в Rust.

Я вижу, что шестнадцатеричное число с плавающей запятой было реализовано в ржавчине как расширение, затем перемещено в отдельный ящик, и теперь оно находится в rust-deprecated и не компилируется с ночной ржавчиной.

Какое будущее у этой функции?

Все 17 Комментарий

Я играл с этой проблемой и пришел к выводу, что это, к сожалению, возвращает к проблеме №1306. Текущий лексический анализатор запрещает любой альфа-символ после . из-за этого. Мы можем выборочно разрешить их, когда найден шаблон 0x<digits>. , но он кажется слишком непоследовательным и может потребовать бесконечного просмотра вперед, если мы хотим исключить несоответствие.

Я предлагаю потребовать цифру либо 0x, либо 0b после точки. Это позволяет избежать столкновения и (что любопытно) позволяет переключать основание системы счисления на середину литерала, если вы выберете. И это лишь немного уродливее, чем то, что заставляет писать C99.

@graydon Или мы можем потребовать только нули после точки. (например, 0x1fffffffffffff.0p+972_f64 вместо 0x1.fffffffffffffp+1023_f64 )

Я не считаю, что это обратно несовместимо, переназначение.

принято для этапа завершения функции

посетил для сортировки с 2013-07-15. Мы действительно остановились на синтаксисе здесь? Кажется, это может быть приятной легкой задачей для нового участника, _ если_ мы сможем передать им четкую спецификацию синтаксиса; но если синтаксис все еще находится на стадии разработки, то это утверждение менее верно.

Я думаю, что мы еще не до конца доработали синтаксис, но я должен указать, что было бы необходимо избегать столкновений с суффиксами (некоторые из которых начинаются с f, шестнадцатеричной цифры), поэтому я думаю, что если мы это сделаем, это должно работать только для с указанием мантиссы и только в сочетании с полной экспонентой (в десятичной системе).

Это еще предстоит реализовать.

Не 1.0

Шестнадцатеричные числа с плавающей запятой довольно популярны среди математических библиотек C. И я бы также хотел использовать их в Rust.

Я вижу, что шестнадцатеричное число с плавающей запятой было реализовано в ржавчине как расширение, затем перемещено в отдельный ящик, и теперь оно находится в rust-deprecated и не компилируется с ночной ржавчиной.

Какое будущее у этой функции?

Тоже интересует это. Я хочу реализовать воспроизводимую физическую систему для игры, которая требует согласованных результатов на разных компьютерах. Шестнадцатеричные литералы с плавающей запятой позволили бы мне писать точные побитовые значения с плавающей запятой в тестах и ​​константах.

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

На данный момент ситуация немного неприятная. Процедурные макросы сейчас проходят модернизацию (# 38356), поэтому поддерживать hexfloat в актуальном состоянии, пока это происходит, было бы пустой тратой времени. Но я не знаю, какой будет история после этого.

Если я правильно понимаю, шестнадцатеричные числа с плавающей запятой в C / C ++ существуют, потому что не гарантируется правильное округление десятичных чисел с плавающей запятой [1]. В Rust, однако, после # 27307 --- я подозреваю, что это не обязательно намеренно! --- почти все десятичные числа с плавающей запятой (# 31407 описывает крайние случаи, которые практически не имеют значения) должны округляться до ближайшего, поэтому вы можете просто дать rustc соответствующее количество (скажем, 30) дробных цифр, и вы получите правильно округленное число. На данный момент это был бы «практический» ответ.

Одна вещь, для которой я все еще считаю актуальной шестнадцатеричные числа с плавающей запятой, - это преобразование из C / C ++. Вы бы не захотели сами преобразовывать все шестнадцатеричные числа с плавающей запятой в десятичные :) Недавно я написал экспериментальный процедурный макрос, который делает именно это, преобразовывая шестнадцатеричные числа с плавающей запятой в десятичные числа с плавающей запятой (что rustc может понять), но не хотел выпускать его, потому что пока что статус-кво не был гарантирован - на мой взгляд, это чистая удача. Если есть способ построить число с плавающей запятой с точным битовым шаблоном только из constexprs, я адаптирую его.

[1] Например, ISO C99 требует, чтобы десятичные числа с плавающей запятой были преобразованы в представимое число в пределах ± 1,5 ulps («результатом является либо ближайшее представимое значение, либо большее или меньшее представимое значение, непосредственно смежное с ближайшим представимым значением» ).

@lifthrasiir , рано или поздно я хотел бы исправить https://github.com/jameysharp/corrode/issues/73 , правильно переведя шестнадцатеричные числа C в Rust, поэтому я хотел бы лучше понять ваш комментарий. Я еще недостаточно читал по вопросам с плавающей запятой, чтобы понять, что здесь происходит.

Вы говорите, что из-за ошибок компилятора Rust каждый шестнадцатеричный литерал с плавающей запятой может быть преобразован в десятичный литерал с плавающей запятой, который компилятор Rust преобразует в тот же битовый шаблон? Если так, я был бы счастлив, если бы Коррод сделал это преобразование. Можете ли вы порекомендовать мне ссылку на алгоритм, который правильно выполняет это преобразование? (Указатель на ваш процедурный макрос был бы отличным, но в идеале я бы тоже хотел процитировать статью или книгу.)

Тем не менее, я полагаю, что точная десятичная версия шестнадцатеричного числа с плавающей запятой может занимать значительно больше цифр (верно?), Поэтому, возможно, шестнадцатеричную версию с плавающей запятой легче читать и понимать, по крайней мере, для людей, которые достаточно заботятся о числовой точности, чтобы использовать их. . Если шестнадцатеричные числа с плавающей запятой являются предпочтительной формой для этих чисел, я бы сказал, что Rust должен их поддерживать. Итак, IMO, здесь поможет больше отзывов от людей, которые использовали шестигранные поплавки.

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

Я считаю, что да.

Можете ли вы порекомендовать мне ссылку на алгоритм, который правильно выполняет это преобразование?

Вам не нужно это реализовывать, потому что текущий компилятор и стандартная библиотека Rust реализуют все необходимые алгоритмы (что сложнее :-). Если вам действительно нужны ссылки, см. Следующее:

  • Преобразование из двоичного в десятичное ("flt2dec", # 24612) является гибридом [Dragon4] и [Grisu3].

    • [Dragon4]: Burger, RG и Dybvig, RK, 1996. Быстрая и точная печать чисел с плавающей запятой. СИГПЛАН Нет. 31, 5 (май 1996 г.), 108-116.
    • [Grisu3]: Флориан Лойч. 2010. Быстрая и точная печать чисел с плавающей запятой с целыми числами. СИГПЛАН Нет. 45, 6 (июнь 2010 г.), 233-243.
  • Преобразование десятичного числа в двоичное (dec2flt, # 27307) - это пара алгоритмов, описанных [Clinger]. (Я сам их не реализовал, поэтому мои знания о них ограничены.)

    • [Клингер]: Уильям Д. Клингер. 1990. Как правильно читать числа с плавающей запятой. СИГПЛАН Нет. 25, 6 (июнь 1990 г.), 92-101.

Для записи, моя реализация - lifthrasiir / hexf (опубликована прямо сейчас, еще не в crates.io). Не стесняйтесь забирать.

Тем не менее, я полагаю, что точная десятичная версия шестнадцатеричного числа с плавающей запятой может принимать значительно больше цифр (верно?), [...] Если шестнадцатеричные числа с плавающей запятой являются предпочтительной формой для этих чисел, я бы сказал, что Rust должен их поддерживать. . [...]

Не совсем так, например, 0x1.999999999999bp-4 = 0.10000000000000002 . У меня нет мнения о том, должен ли Rust поддерживать шестнадцатеричные числа с плавающей запятой или нет.

Я официально опубликовал hexf в crates.io . @jameysharp , я думаю, вы можете использовать hexf-parse для своей работы? (Синтаксис без подчеркивания должен быть почти идентичен C99 hexadecimal-floating-constant non-terminal без необязательного floating-suffix .)

Изменить: ага, я пропустил один случай. 0x1p1 должно быть действительным, но hexf его не распознает; хотя, вероятно, это легко объяснить.

Подобный вариант использования и для меня; Я хотел бы иметь возможность генерировать код ржавчины из компилятора без потери точности для литералов с плавающей запятой.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги