Какая точность печати требуется для __float128, чтобы не потерять информацию? - PullRequest
6 голосов
/ 28 января 2012

Я пытаюсь напечатать __float128 с помощью libquadmath, например:

quadmath_snprintf(s, sizeof(s), "%.30Qg", f);

Со следующими тремя составами:

  1. Выход должен соответствовать следующей продукции:

     number = [ minus ] int [ frac ] [ exp ]
    
     decimal-point = %x2E       ; .
    
     digit1-9 = %x31-39         ; 1-9
    
     e = %x65 / %x45            ; e E
    
     exp = e [ minus / plus ] 1*DIGIT
    
     frac = decimal-point 1*DIGIT
    
     int = zero / ( digit1-9 *DIGIT )
    
     minus = %x2D               ; -
    
     plus = %x2B                ; +
    
     zero = %x30                ; 0
    
  2. Учитывая, что любой вход __float128 «i», который был напечатан в строку, соответствующую вышеуказанному производственному «s», а затем «s» сканируется обратно в __float128, «j» - «i» должен быть поразрядным на «j» - т.е. никакая информация не должна быть потеряна. По крайней мере, для некоторых значений это невозможно (NaN, Infinity), каков полный список этих значений?

  3. Не должно быть другой строки, удовлетворяющей двум вышеуказанным критериям, которая короче кандидата.

Есть ли строка формата quadmath_snprintf, которая удовлетворяет вышеуказанным требованиям (1, 3 и 2, когда это возможно)? Если так, что это?

Каковы значения __float128, которые не могут быть представлены достаточно точно, чтобы удовлетворить пункт 2 вышеуказанным производством? (например, Nan, +/- Infinity и т. д.) Как я могу определить, содержит ли __float128 одно из этих значений?

Ответы [ 2 ]

1 голос
/ 29 января 2012

Если вы используете x86, то тип GCC __float128 является программной реализацией формата IEEE 754-2008 binary128.Стандарт IEEE 754 требует, чтобы двоичный код -> char -> двоичный код туда и обратно восстанавливал исходное значение, если символьное представление содержит 36 значащих (десятичных) цифр.Таким образом, форматная строка %.36Qg должна это сделать.

Не требуется, чтобы в обратном направлении NaN восстанавливалось исходное битовое значение.

Что касается вашего требования №3, libquadmath не содержит кодадля такого рода форматирования «кратчайшего представления», например, в духе Steele & White paper или кода Дэвида Гея.

0 голосов
/ 28 января 2012

Моя интуиция подсказывает мне, что двоичная дробь 0,1111 ... 1 (128 единиц);также равное 1-1 / 2 ** 128 будет производить наибольшее количество переполнений при преобразовании в десятичную.Преобразуйте это значение в десятичное (у меня сейчас нет пакета bignum), посчитайте количество цифр, добавьте 2-3 сверху, и вы должны быть в безопасности.У меня нет математического доказательства того, что этого достаточно.

Если важна точность ввода / вывода, я бы предпочел выводить число с плавающей запятой в виде шестнадцатеричной строки.Точный ввод-вывод с плавающей запятой трудно понять, и библиотека может содержать ошибки в этом отношении.

...