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

49
задан Jonathan Leffler 9 November 2009 в 05:52
поделиться

6 ответов

Стандартный заголовок в C или в C ++, содержит несколько констант для делать с диапазоном и другими показателями типов с плавающей запятой. Одним из них является DBL_MAX_10_EXP , самая большая степень степени 10, необходимая для представления всех двойных значений. Поскольку для 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
34
ответ дан 7 November 2019 в 11:52
поделиться

Согласно IEEE 754-1985 , самая длинная запись для значения, представленного типом double, например:

-2.2250738585072020E-308

имеет 24 символа .

15
ответ дан 7 November 2019 в 11:52
поделиться

Вы можете использовать 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
ответ дан 7 November 2019 в 11:52
поделиться

Вы можете контролировать количество цифр в строковом представлении когда вы конвертируете float / double в строку, устанавливая точность. Тогда максимальное количество цифр будет равно строковому представлению std :: numeric_limits :: 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 цифр.

2
ответ дан 7 November 2019 в 11:52
поделиться

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

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

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

Если у вас 48 бит мантиссы, это займет около 16 десятичных цифр.

1
ответ дан 7 November 2019 в 11:52
поделиться

1024 недостаточно, наименьшее отрицательное значение типа double состоит из 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
1
ответ дан 7 November 2019 в 11:52
поделиться