Ответ 1
Для long double
вы должны использовать формат "%Lf"
. Форматирование с малым L (т.е. "%Lf"
) не влияет на системы POSIX (см. спецификация).
Я работаю над приложением, которое работает с различными вариантами Unix и Windows 32bit и 64-битной ОС.
Я использую тип данных long double
, когда я делаю sprintf()
и использовал long double
с %lf
в нем, тогда он отлично работает с окнами, не дает какой-либо ошибки, однако на платформе Solaris она дает ядро свалка.
Пример кода для этой же проблемы следующий.
void main(){
string size = "16622";
string sizeFact = "20";
long long sizeLongLong = strtoll(size);
int factInt = atoi(sizeFact);
long double sizeLongDouble = (long double) sizeLongLong/pow(2, factInt);
char buf[512];
sprintf(buf, "%.3lf %s", sizeLongDouble, "str");
}
Как упоминалось выше, код отлично работает на Windows 32bit и 64bit, однако для sprintf он дает мне ядро на Solaris.
Я попробовал лить тип в sprintf, он работал нормально.
sprintf(buf, "%.3lf %s", (double) sizeLongDouble, "str");
Что такое спецификатор формата для long double
?
Какая ошибка я делаю здесь, я использую неправильный спецификатор формата, из-за которого он дает ядро?
Почему мне нужно вводить еще один раз в sprintf()?
Для long double
вы должны использовать формат "%Lf"
. Форматирование с малым L (т.е. "%Lf"
) не влияет на системы POSIX (см. спецификация).
Документация делает это довольно ясным:
L
Следующее преобразование a, A, e, E, f, F, g или G соответствует длинному двойному аргументу. (C99 > разрешает% LF, но SUSv2 не делает.)
Итак, вы должны использовать %Lf
.
В зависимости от компилятора я видел %Lf
и %llf
попробовать оба и посмотреть, что работает. Используемый %Lf
- это спецификатор формата для double
не для long double
. Я полагаю, что на g++
вы должны использовать %llf
, а на визуальной студии - %Lf
.
Я бы добавил это как комментарий, но пока не могу этого сделать. Также важно отметить, что вы также можете использовать обозначение "p" экспоненциального значения для long double
следующим образом:
%Lf
%Le
%La