2017-01-28 11 views
-1

В приведенном ниже примере
выходы с другим спецификатором формата

#include <stdio.h> 
    #include <math.h> 
    int main(void) { 
     int t,n,x,i; 
     long int num; 
     scanf("%d",&t); 
     while(t--){ 
      scanf("%d",&n);num=0; 
      for(i=1;i<=n;i++){ 
      scanf("%d",&x); 
      num=num+(x*pow(10,(n-i))); 
      } 
      printf("%ld\n",num); 
     } 
     return 0; 
    } 

Образца занимает время 0.03s для набора входных данных.
Когда я изменил спецификатор формата от %ld до %d, в printf образец занял время 0,02 с для того же значения и количества ввода. В этом случае num имеет тип long int и оценивается в этой форме. Почему это происходит, даже если результат имеет одинаковый размер в обоих случаях?

+0

Значит, вы не изменили 'num' в соответствии с спецификатором формата'% d'? Чтобы получить реалистичные тайминги, вам нужно многократно повторять операцию, так что это займет несколько секунд. –

+0

@WeatherVane num остается в типе 'long int' в обоих случаях –

+0

Что такое' sizeof (long) 'и' sizeof (int) '? Они оба «4» на моей машине. –

ответ

0

Насколько точны ваши результаты по времени? Если вы использовали команду time, она дает только два десятичных знака, поэтому разница между 0.03 и 0.02 несущественна (например, на самом деле это могло быть 0.02500001 и 0.02499999 до округления). Используйте более длинный вход и повторите тест несколько раз, усредняя результат и глядя на стандартное отклонение, чтобы увидеть, является ли разница статистически значимым.

Это, в зависимости от вашей платформы, int и long int могут иметь одинаковый размер, что делает их эквивалентными. Если это не так, это зависит от того, действительно ли библиотека C на вашей платформе использует другую процедуру для синтаксического анализа длинных ints по сравнению с обычными ints. Я бы предположил, что внутри он всегда использует ту же самую процедуру, которая имеет самый длинный размер целого числа, и просто возвращает результат в запрошенный тип.

+0

Я использовал онлайн-идею, чтобы получить время и выполнить программу. Имеет ли это значение? –

+0

Плюс, тип 'num' во время выполнения программы одно и то же: все то же самое, что и спецификатор формата printf. Итак, как печатать один и тот же результат, используя два разных спецификатора формата, делает разницу во времени? –

+0

Да! Я проверил код сборки из двух экземпляров, и получается, что тот, у которого '% ld' в printf нуждается в большей обработке, чем в случае с'% d', хотя единственное различие между двумя кодами - printf. Спасибо. –

0

Когда я изменил спецификатор формата% от ЛД до% д ...

... это неопределенное поведение (УБ).

long int num; 
... 
printf("%d\n",num); // mis-matched specifier and data type. 

Даже если ОП могут быть получены ожидаемые результаты с ООН-размещены входы, сравнение производительности moot за счет UB.


При проведении сопоставлений времени в набор данных, порядок испытаний (из-за кэширования памяти) и многие факторы способствуют. Для хорошего анализа почтовый код, который не имеет неопределенного поведения и при запуске показывает разницу для себя.

+0

Да, я знаю, что это UB, но я действительно хотел понять это неопределенное поведение. Возможно ли получить объяснение или даже ссылку на то, как работает это неопределенное поведение? –

+0

Да. Изучить код, созданный компилятором, является самым прямым и конечно правильным ответом - или вы ищете предположения? В этом случае на этом посту не хватает необходимой информации, такой как платформа/процессор, компилятор, версия и данные, используемые для хорошей догадки. – chux

+0

Да! Я понял ! Я рассмотрел код сборки двух отдельных кодов и нашел разницу. Предположительно, код, в котором рассматривается '% d', использует только' .lc0', тогда как код, где рассматривается '% ld', использует' .lc0' и '.lc2'. Так что в основном, считает большую память. Большое вам спасибо за помощь! Но Г. Слипен был прав, и я должен был бы принять его ответ, так как я могу принять только один. –

 Смежные вопросы

  • Нет связанных вопросов^_^