6

Из моего предыдущего вопроса "Is floating point precision mutable or invariant?" Я получил response, который сказал,У плавающих, парных и длинных парных разрядов гарантированная минимальная точность?

C обеспечивает DBL_DIG, DBL_DECIMAL_DIG и их поплавка и длинные двойные аналоги. DBL_DIG указывает минимальную относительную десятичную точность . DBL_DECIMAL_DIG можно рассматривать как максимальную относительную точность .

Я посмотрел эти макросы вверх. Они находятся в заголовке <cfloat>. Из cplusplus reference page перечислены макросы для float, double и long double.

Вот макросы для минимальных значений точности.

FLT_DIG 6 or greater

DBL_DIG 10 or greater

LDBL_DIG 10 or greater

Если бы я взял эти макросы по номинальной стоимости, я бы предположить, что float имеет минимальный десятичную точность 6, в то время как double и long double имеют минимальную десятичную точность 10. Однако, будучи большим мальчиком, я знаю, что некоторые вещи могут быть слишком хорошими, чтобы быть правдой.

Поэтому я хотел бы знать. Имеют ли плавающие, удвоенные и длинные удвоения гарантированную минимальную десятичную точность, и является ли эта минимальная десятичная точность значениями макросов, приведенными выше?

Если нет, то почему?


Примечание: Предположим, что мы используем язык программирования C++.

+0

Что означает «десятичная точность»? – tmyklebu

+0

@tmyklebu ссылается на первую ссылку в вопросе выше. – Bryan

+0

Я также не могу понять смысл вашей первой ссылки. В каком заявлении вы хотите включить FLT_DIG? Кроме того, вы знаете, что это, как правило, форматы radix-2, а не radix-10, верно? – tmyklebu

ответ

5

Если std::numeric_limits<F>::is_iec559 верно, то гарантии IEEE 754 standard применяются к плавающему точечный тип F.

В противном случае (и в любом случае), минимальная допустимая значения символов, таких как DBL_DIG определены стандартом C, который, неоспоримо для библиотеки, “ включен в [с ++, C] Международный стандарт по ссылке ”, как цитируется из С ++ 11 §17.5.1.5/1.

Редактировать: Как отметили КИ в комментариях здесь,

<climits> и <cfloat> являются нормативным включены §18.3.3 [c.limits]; минимальные значения указаны в свою очередь, в §5.2.4.2.2 стандарта C

К сожалению, для формальной точки зрения, прежде всего, что цитата из C++ 11 является из раздела 17.5, который только информативный, а не нормативный. И, во-вторых, формулировка в стандарте C, что указанные здесь значения минимальны, также находится в разделе (приложение E стандарта C99), которое является информативным, а не нормативным. Поэтому, хотя это можно рассматривать как гарантию на практике, это не формальная гарантия.


Один сильный признак того, что в-практике минимальная точность для float 6 десятичных цифр, что ни одна реализация не будет давать меньше:

операций вывода по умолчанию для точности 6, и это нормативный текст ,

Отказ от ответственности: Возможно, существует дополнительная формулировка, которая предоставляет гарантии, которых я не заметил. Не очень вероятно, но возможно.

+0

'' и '' нормативно включены в §18.3.3 [c.limits]; минимальные значения указываются поочередно в п. 5.2.4.2.2 стандарта С. –

+0

@ T.C .: Спасибо! Обновлено и удалено отказ от ответственности (больше не требуется). :) –

0

Do поплавки, удваивается, и длинные двойники имеют гарантированный минимальный десятичную точность, и это минимальное десятичная точность значения макросов, приведенные выше?

Я не могу найти ни одного места в стандарте, которое гарантирует минимальные значения для десятичной точности.

Следующая цитата из http://en.cppreference.com/w/cpp/types/numeric_limits/digits10 может быть полезно:

Пример

8-битный двоичный тип может представлять любое двузначное десятичное число точно, но 3-значный десятичных чисел 256. .999 не могут быть представлены. Значение digits10 для типа 8-битном 2 (8 * std::log10(2) 2,41)

стандарт 32-битный IEEE 754 типа с плавающей точкой имеет 24 бит дробная часть (23 бита записывается, один подразумевается), что может свидетельствовать что он может представлять семизначные десятичные знаки (24 * std::log10(2) - 7.22), но относительные ошибки округления неравномерны, а некоторые значения с плавающей запятой с 7 десятичными разрядами не выдерживают преобразования в 32-битный поплавок и обратно: наименьший положительный пример - 8.589973e9, который становится 8.589974e9 после обратного перехода. Эти ошибки округления не могут превышать один бит в представлении, а digits10 рассчитывается как (24-1)*std::log10(2), что составляет 6,92. Результаты округления в значении 6.

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

5.2.4.2.2 Характеристики плавающих типов

...

9 Значения, приведенные в следующем списке, должны быть заменены постоянными выражениями с реализацией -определенные значения, которые больше или равны по величине (по абсолютной величине) тем, которые показаны, с теми же знаками

...

- количество десятичных цифр, q, так что любое число с плавающей запятой с q десятичными цифрами может быть округлено до числа с плавающей запятой с цифрами p radix b и обратно без изменения на q десятичных цифр,

...

FLT_DIG 6
DBL_DIG 10
LDBL_DIG 10

+0

Re "стандарт может гарантировать точность 2 для 8-битных представлений поплавков", что противоречило бы ограничениям (неформально), требуемым стандартом C, а также (нормативной) требуемой по умолчанию точности 6 для вывода. –

+0

С битом знака и 7 битами мантиссы (для получения двухзначной точности) не было места для экспоненты, что привело бы к идее числа чисел с плавающей запятой ad absurdum. –

+0

@ Cheersandhth.-Alf, означает ли это, что подтверждающая реализация должна иметь как минимум 32-битное представление для 'float'? –

0

Стандарт C++ ничего не говорит о ограничениях на типы с плавающей точкой. Вы можете интерпретировать инкорпорацию C стандарта «по ссылке», как вы хотите, но если взять за пределы, указанные там (N1570), раздел 5.2.4.2.2 15 подпункта:

Пример 1 Следующие описывает искусственное представление с плавающей точкой, которая отвечает минимальным требованиям настоящего стандарта, а также соответствующие значения в заголовке для типа поплавка:
FLT_RADIX 16
FLT_MANT_DIG 6
FLT_EPSILON 9.53674316E-07F
FLT_DECIMAL_DIG 9
FLT_DIG 6
FLT_MIN_EXP -31
FLT_MIN 2.93873588E-39F
FLT_MIN_10_EXP -38
FLT_MAX_EXP +32
FLT_MAX 3.40282347E+38F
FLT_MAX_10_EXP +38

По этой секции, float, double и long double обладают этими свойствами по крайней мере *.

0

Конкретно. Поскольку мой компилятор использует стандарт IEEE 754, тогда точность моих десятичных цифр равна . Гарантируется для 6-9 значащих десятичных цифр для float и от 15 до 17 значащих десятичных цифр для double. Кроме того, поскольку long double на моем компиляторе имеет тот же размер, что и double, он также имеет от 15 до 17 значащих десятичных цифр.

Эти диапазоны могут быть проверены от IEEE 754 single-precision binary floating-point format: binary32 и IEEE 754 double-precision binary floating-point format: binary64 соответственно.

Смежные вопросы