Какова максимальная длина в символах, необходимых для представления любого двойного значения?
Когда я конвертирую беззнаковый 8-битный int в строку, тогда я знаю, что результат всегда будет не более 3 символов (для 255), а для подписанного 8-битного int нам нужно 4 символа, например. "-128".
Теперь то, что мне действительно интересно, - это то же самое для значений с плавающей запятой. Какое максимальное количество символов требуется для представления любого значения "double" или "float" в виде строки?
Предположим, что обычный C/С++ двойной (IEEE 754) и нормальный десятичный разветвление (т.е. нет% e printf-форматирование).
Я даже не уверен, будет ли действительно небольшое число (т.е. 0.234234) длиннее, чем действительно огромные числа (числа, представляющие целые числа)?
Ответы
Ответ 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
Ответ 2
http://en.wikipedia.org/wiki/IEEE_754-1985
Самый длинный представляемый двойной:
-2.2250738585072020E-308
имеет 24 символа.
Ответ 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.
С уважением.