Блог пользователя Sklyack

Автор Sklyack, 13 лет назад, По-русски

Имеются посылки по A (div. 2) с использованием компилятором GNU C++, отличаются только в одной строке спецификатором вывода:

http://www.codeforces.ru/contest/127/submission/844205
Обе посылки дают WA#1. Компилил у себя g++ -ом код второй посылки -- программа выдаёт правильный ответ на тест #1.
Аналогичная посылка с MS C++ даёт AC:
Очевидно проблема в выводе long double. Подскажите, как правильно вводить/выводить long double с использованием printf местным g++ ? Есть ли способ без преобразования в double?

  • Проголосовать: нравится
  • -3
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
В MS С++ sizeof(long double) == sizeof(double), гарантирую.
13 лет назад, # |
  Проголосовать: нравится +26 Проголосовать: не нравится
Примерно так:
long double a;
...
printf("%.10lf", (double)a);
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    а без преобразования возможно?

    • 13 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится

      AFAIK, нет.

      Но обычно при выводе особо большую точность не требуют, потому можно считать всё в long double и выводить как double.

    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      long double answ = 3.141592;
      printf("%Lf", answ);

      Мы с этим приколом 2 года назад в Харькове столкнулись. Даже реджадж хотели требовать.
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Не вышло ответить куда хотел.

To anonymous:

Вот именно, в MS С++ sizeof(double)==8, а в g++ sizeof(long double)>8, поэтому считаю g++ предпочтительней в задачах, где применяется арифметика с плавающей точкой.


  • 13 лет назад, # ^ |
    Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

    Из известного мне. Участниками CF найдено 2 бага в gcc и 0 багов в MS VCPP. IDE для MS VCPP значительно лучше (можно VS приучить к gcc? не думаю). Таким образом, отправка на gcc стоит мне лишних пары минут для того, чтобы скомпилировать под ней решение (на стороне сервера, заодно с макс-тестом), и область применения ограничена близкими к ТЛ случаями (оптимизатор на gcc лучше).

    P.S. сравнивать sizeof в разных С++ компиляторах - не по стандарту. sizeof(long double) == 2 может быть для 160-битного типа long double.

    • 13 лет назад, # ^ |
        Проголосовать: нравится +4 Проголосовать: не нравится
      Прошу прощения, но разве sizeof возвращает не размер в байтах?
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Это если под Windows сидишь.
      Хотя я вот пишу под убунтой, но отправляю все равно под MSVC, потому что тут GCC из MinGW -- как-то нет, спасибо...

    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      К сожалению, иногда два "лишних" байта long double иногда критичны в плане точности. Например я так и не сдал диаграмму Вороного на тимусе (задача 1369), как раз из-за того, что точности в даблах не хватает.
      Касаемо глюков - в VCPP мы как-то наталкивались на веселый спецэффект, когда оптимизатор вообще вырезал функцию, обновляющую что-то в дереве отрезков. Так и не поняли, почему она ему не нравится.

      P.S. Ни в коем случае не ругаю VCPP - просто везде есть баги, да. А IDE в VS отменная. В частности, нравится тем, что не особо тормозит даже на древних компах :-)
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Видимо никаких нормально работающих спецификаторов для long double нет. Для вывода проще всего выводить приводя к double как написано выше. А для ввода я обычно пишу так:

typedef long double ld;
inline ld nextLd()
{
double ans;
scanf("%lf", &ans);

return ld(ans);
}
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Обычно, если требуется большая точность вывода, то самого вывода мало, так что std::cout в помощь - он для всех типов корректно выводит. Используйте cout.setprecision(20); cout << fixed; - для того чтобы много знаков после точки выводить.

Сам любитель printf, но в случае long double можно и поступиться.

  • 9 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Правда? cout умеет выводить long double в G++? попробуйте, иначе бы не было таких вопросов

    • 9 лет назад, # ^ |
        Проголосовать: нравится +16 Проголосовать: не нравится

      Умеет

      В специфических версиях gcc на специфических для него платформах (windows) имеется баг с выводом. Но это не значит что gcc не умеет.

      4 года назад, когда писался комментарий, этой бажной версии ещё не существовало.

    • 9 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Вы говорите про MinGW (у него, да, есть несколько бажных версий) или про G++?