Подтвердить что ты не робот

Какова максимальная длина в символах, необходимых для представления любого двойного значения?

Когда я конвертирую беззнаковый 8-битный int в строку, тогда я знаю, что результат всегда будет не более 3 символов (для 255), а для подписанного 8-битного int нам нужно 4 символа, например. "-128".

Теперь то, что мне действительно интересно, - это то же самое для значений с плавающей запятой. Какое максимальное количество символов требуется для представления любого значения "double" или "float" в виде строки?

Предположим, что обычный C/С++ двойной (IEEE 754) и нормальный десятичный разветвление (т.е. нет% e printf-форматирование).

Я даже не уверен, будет ли действительно небольшое число (т.е. 0.234234) длиннее, чем действительно огромные числа (числа, представляющие целые числа)?

4b9b3361

Ответ 1

Стандартный заголовок <float.h> в C или <cfloat> в С++ содержит несколько констант, относящихся к диапазону и другим метрикам типов с плавающей точкой. Один из них DBL_MAX_10_EXP, наибольший показатель степени в степени -10 должен представлять все значения double. Поскольку 1eN требуется N+1 цифр для представления, и может быть и отрицательный знак, тогда ответ

int max_digits = DBL_MAX_10_EXP + 2;

Это предполагает, что показатель больше, чем число цифр, необходимых для представления наибольшего возможного значения мантиссы; в противном случае также будет десятичная точка, за которой следует больше цифр.

КОРРЕКЦИЯ

Самое длинное число - наименьшее представимое отрицательное число: ему нужно достаточно цифр, чтобы охватить как экспонента, так и мантиссу. Это значение -pow(2, DBL_MIN_EXP - DBL_MANT_DIG), где DBL_MIN_EXP отрицательно. Довольно легко увидеть (и доказать по индукции), что -pow(2,-N) нужны символы 3+N для ненаучного десятичного представления ("-0.", за которым следует N цифр). Итак, ответ

int max_digits = 3 + DBL_MANT_DIG - DBL_MIN_EXP

Для 64-битного IEEE-двойника мы имеем

DBL_MANT_DIG = 53
DBL_MIN_EXP = -1023
max_digits = 3 + 53 - (-1023) = 1079

Ответ 3

Вы можете использовать snprintf(), чтобы проверить, сколько символов вам нужно. snprintf() возвращает количество символов, необходимых для печати того, что передается ему.

/* NOT TESTED */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char dummy[1];
    double value = 42.000042; /* or anything else */
    int siz;
    char *representation;
    siz = snprintf(dummy, sizeof dummy, "%f", value);
    printf("exact length needed to represent 'value' "
           "(without the '\\0' terminator) is %d.\n", siz);
    representation = malloc(siz + 1);
    if (representation) {
        sprintf(representation, "%f", value);
        /* use `representation` */
        free(representation);
    } else {
        /* no memory */
    }
    return 0;
}

Примечание: snprintf() - это функция C99. Если компилятор C89 предоставляет его как расширение, он может не выполнять то, что ожидает ожидаемая программа.

Изменить: Изменена ссылка на snprintf() на ту, которая фактически описывает функциональность, налагаемую стандартом C99; описание в исходная ссылка неверно.
2013: изменил ссылку на сайт POSIX, который я предпочитаю на сайт первого редактирования.

Ответ 4

Вы можете управлять количеством цифр в строчном представлении, когда вы конвертируете float/double в строку, задавая точность. Максимальное количество цифр будет равно строковому представлению std::numeric_limits<double>::max() с указанной вами точностью.

#include <iostream>
#include <limits>
#include <sstream>
#include <iomanip>

int main()
{
 double x = std::numeric_limits<double>::max();

 std::stringstream ss;
 ss << std::setprecision(10) << std::fixed << x;

 std::string double_as_string = ss.str();
 std::cout << double_as_string.length() << std::endl;
}

Таким образом, наибольшее количество цифр в double с точностью 10 составляет 320 цифр.

Ответ 5

1024 недостаточно, наименьшее отрицательное двойное значение имеет 1077 десятичных цифр. Вот какой код Java.

double x = Double.longBitsToDouble(0x8000000000000001L);
BigDecimal bd = new BigDecimal(x);
String s = bd.toPlainString();
System.out.println(s.length());
System.out.println(s);

Вот результат работы программы.

1077
-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625

Ответ 6

Зависит от того, что вы подразумеваете под "представлять". Десятичная дробь не имеет точных представлений с плавающей запятой. Когда вы конвертируете десятичную дробь → двоичную дробь → десятичную, у вас нет точных десятичных представлений и будут иметь шумовые биты в конце двоичного представления.

Вопрос не касался начинать с десятичной, но весь исходный код (и должен вводиться пользователем) десятичный и включает возможную проблему усечения. Что означает "точный" в этих условиях?

В принципе, это зависит от вашего представления с плавающей запятой.

Если у вас есть 48 бит мантиссы, это занимает около 16 десятичных цифр. Показателем может быть оставшийся 14 бит (около 5 десятичных цифр).

Эмпирическое правило состоит в том, что количество бит составляет около 3х число десятичных цифр.

Ответ 7

"Какова максимальная длина в символах, необходимых для представления любого двойного значения?"

Точный ответ на этот вопрос: 8 символов ASCII - в шестнадцатеричном формате, исключая префикс '0x' - точность 100%:) (но это не просто шутка)

Используемая точность IEEE-754 double составляет около 16 десятичных цифр - поэтому исключая образовательные цели, представления дольше, чем это просто трата ресурсов и вычислительной мощности:

  • Пользователи не получают больше информации, когда видят 700-значный номер на screeen.

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

Если кто-то нуждается в лучшей реальной точности, то там 80-битный длинный двойной с точностью до 18 цифр или f.e. libquadmath.

С уважением.