Как печатать долго долго

Я делаю программу, которая приближается к PI, и я пытаюсь использовать long long, но она не работает. Вот код

#include<stdio.h>
#include<math.h>
typedef long long num;
main(){
    num pi;
    pi=0;
    num e, n;
    scanf("%d", &n);
    for(e=0; 1;e++){
      pi += ((pow((-1.0),e))/(2.0*e+1.0));
      if(e%n==0)
        printf("%15lld -> %1.16lld\n",e, 4*pi);
      //printf("%lld\n",4*pi);
    }
}

person Carlos    schedule 19.06.2011    source источник
comment
Я предполагаю, что ваша проблема больше связана с scanf, чем с printf.   -  person Nemo    schedule 19.06.2011
comment
pow((-1.0),e) лучше было бы выразить как e % 2 ? 1 : -1   -  person phuclv    schedule 29.12.2017


Ответы (4)


%lld — это стандартный способ C99, но он не работает с компилятором, который я использую (mingw32-gcc v4.6.0). Способ сделать это на этом компиляторе: %I64d

Итак, попробуйте следующее:

if(e%n==0)printf("%15I64d -> %1.16I64d\n",e, 4*pi);

и

scanf("%I64d", &n);

Единственный известный мне способ сделать это полностью переносимым способом — использовать определения в <inttypes.h>.

В вашем случае это будет выглядеть так:

scanf("%"SCNd64"", &n);
//...    
if(e%n==0)printf("%15"PRId64" -> %1.16"PRId64"\n",e, 4*pi);

Это действительно очень уродливо... но, по крайней мере, это портативно.

person karadoc    schedule 19.06.2011
comment
Здесь виноват не ваш компилятор, а ваша библиотека C. Вы используете библиотеку Microsoft C, которая не поддерживает %lld, являющуюся функцией C99 (хотя и inttypes.h). - person caf; 20.06.2011
comment
Чтобы быть более конкретным, это msvcrt.dll, древняя (около 1998 г.) версия стандартной библиотеки C, которая изначально была написана для VC++ 6.0 и поставляется с Windows для целей обратной совместимости. MinGW использует эту древнюю версию, потому что это единственная версия, поставляемая из коробки с Windows. Но современная среда выполнения VC++ правильно обрабатывает %lld. - person Pavel Minaev; 16.09.2016
comment
Visual C++ 2013, похоже, поддерживает элемент формата %lld - person user1741137; 03.05.2017
comment
@PavelMinaev msvcrt.dll, который поставляется с Windows, не древний. - person Pavel P; 18.05.2017
comment
Конечно, он был исправлен, но я не слышал о каких-либо обновлениях его фактических функций со времен VC++ 6.0. - person Pavel Minaev; 19.05.2017
comment
Одним из преимуществ использования нового WSL является то, что вы можете в наши дни писать C с обновленным GCC или CLANG. Гораздо более совместим, чем MINGW. - person Brian Bulkowski; 25.05.2020

  • Ваш оператор scanf() также должен использовать %lld.
  • В вашем цикле нет условия завершения.
  • В выражении слишком много скобок и слишком мало пробелов.

    pi += pow(-1.0, e) / (2.0*e + 1.0);
    
  • Вы добавляете единицу на первой итерации цикла, а затем ноль к значению «пи»; это не сильно меняет значение.
  • Вы должны использовать явный возвращаемый тип int для main().
  • В целом, лучше указывать int main(void), когда он игнорирует свои аргументы, хотя это менее категоричное утверждение, чем остальные.
  • Мне не нравится явная лицензия, предоставленная в C99, чтобы опустить возврат из конца main() и не использовать его самостоятельно; Я пишу return 0;, чтобы быть явным.

Я думаю, что весь алгоритм сомнителен, если он написан с использованием long long; тип данных, вероятно, должен быть больше похож на long double%Lf для формата scanf() и, возможно, %19.16Lf для форматов printf().

person Jonathan Leffler    schedule 19.06.2011

Прежде всего, %d для int

Так что %1.16lld не имеет смысла, потому что %d — целое число.

То typedef, который вы делаете, также не нужен, используйте тип прямо перед собой, это делает код более читаемым.

То, что вы хотите использовать, это тип double для вычисления числа пи, а затем использования %f или %1.16f.

person Vinicius Kamakura    schedule 19.06.2011
comment
Это не совсем незаконно... я думаю, это специфично для MSVC. - person user541686; 19.06.2011
comment
Неправильно. Прочтите спецификацию printf. %lld — это именно то, как вы печатаете long long. (Конечно, 1.16 может не делать то, что вы хотите... Но это совершенно правильно. Это означает, что используйте минимальную ширину поля 1 и печатайте 16 цифр.) - person Nemo; 19.06.2011
comment
@Mehrdad Ты имеешь в виду %lld? Это указано в C99 7.19.6.1. - person Pascal Cuoq; 19.06.2011
comment
@Pascal: О, я понятия не имел, тогда даже лучше. @hexa: Извините, я имел в виду lld, а не десятичные точки... Я думал, это то, что вы имели в виду, мой плохой. - person user541686; 19.06.2011
comment
MSVC использует такой формат, как %I64d или %lld для 64-битных форматов long long. - person Jonathan Leffler; 19.06.2011

person    schedule
comment
Хотя этот фрагмент кода может быть решением, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причины вашего предложения кода. - person Rahul Gupta; 29.12.2017
comment
Хотя этот код может решить проблему, включая объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщение и, вероятно, приведет к большему количеству голосов. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для того, кто задает сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются. - person double-beep; 31.03.2019
comment
Конечно, я добавлю больше деталей @double-beep - person Atul Kumar; 31.03.2019