Разные результаты для long long int в c и c ++?

0

Я пытаюсь решить эту проблему problem-> Candy3. Мы должны использовать долгое время для решения этой проблемы. Но когда я использую cin для ввода входных данных, которые больше 10 ^ 19 (я знаю, что это предел длинной длины, но есть ограничение по лимитам, и мы должны выводить правильный ответ), он дает случайные выходы. Принимая во внимание, что, когда я использую scanf(), он печатает правильный ответ.

Это действительно странно. В чем разница b/w scanf и cin. Мой код

#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
    int t,n;
    cin>>t;
    while(t--){
        long long sum=0,sweet;
        cin>>n;
        for(int i=0; i<n; i++){
            //cin>>sweet; printing yes no randomly
            scanf("%lld", &sweet); // working correctly
            sum = (sum + sweet)%n;
        }
        if(sum)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    }
    return 0;
}

EDIT: Это странный вопрос, и в вопросе не указано, что должен быть размер ввода. Вот спецификация ввода -

"Первая строка входного файла содержит целое число T, определяющее количество тестовых примеров. Каждому тесту предшествует пустая строка. Каждый тестовый пример выглядит следующим образом: первая строка содержит N: количество детей. в следующих N строках содержится количество конфет, привезенных одним ребенком ".

  • 0
    вы делаете cin >> integer, но просматриваете в long long int, верно?
  • 0
Показать ещё 6 комментариев
Теги:

3 ответа

3
Лучший ответ

Как отмечают многие люди, вы пытаетесь прочитать целые числа, которые будут переполняться long long.

Разница между scanf и cin.operator>>() отношении переполнения целых чисел заключается в том, что scanf не (обязательно) проверяет целостность переполнения; если число чтения слишком велико, результатом является неопределенное поведение. Как правило, вы найдете неправильное значение в соответствующем аргументе, но никаких гарантий нет.

cin.operator>>(), с другой стороны, проверяет cin.operator>>() переполнения, и если он обнаруживает целочисленное переполнение, он сохраняет максимально возможное целое число указанного типа и помещает поток cin в состояние сбоя. Когда поток находится в состоянии отказа, он остается там до тех пор, пока состояние не будет очищено; кроме того, любое последующее использование cin.operator>>() ничего не сделает, если поток находится в состоянии сбоя.

Следовательно, как только вы попытаетесь прочитать целое число, которое слишком велико с cin.operator>>(), ваш код найдет sweet который будет максимально long long при каждом последующем чтении.

Поэтому при использовании отформатированного ввода C++ вам нужно всегда проверять наличие сбоя и делать что-то подходящее.

  • 0
    Спасибо, хорошее объяснение, и теперь я знаю, почему моя программа заканчивала работу посередине, когда я использовал cin >> для очень больших входов, тогда как scanf () работал нормально. Я думаю, мой ответ был принят с помощью scanf (), потому что он не заканчивался посередине для очень больших входов. Я прав?
  • 0
    Дело в том, что cin >> перестает читать после ошибки, включая переполнение. Так что звонки в cin >> становятся бездействующими. Сладкое не меняется. n не меняется. Я не знаю, что вы имеете в виду под «он печатает да и нет вместе», но я полагаю, что это потому, что он останавливает чтение, но продолжает зацикливаться, так что вы получаете больше выходных данных, чем ожидаете.
Показать ещё 1 комментарий
3

Вы говорите, что вводите значения, превышающие 10 19. Это, вероятно, переполнится long long.

Тип long long должен быть не менее 64 бит в ширину, и на каждом компиляторе я видел его ровно 64 бита в ширину. Это означает, что максимально возможное значение long long составляет 2 63 -1, или 9,223,372,036,854,775,807, что составляет приблизительно 9 * 10 18.

Если вы введете значение 10 19 или 10 000 000 000 000 000, оно переполнится. Если cin <<... встречается с числовым переполнением, он потерпит неудачу; вы не проверили это.

Я не верю, что использование scanf решит эту проблему. scanf имеет неопределенное поведение, если он считывает число за пределами диапазона указанного типа; вероятным результатом является сохранение стоимости мусора. Я могу только догадываться, что вы случайно вводите меньшее число с версией scanf вашей программы, чем с версией cin >>..., и не заметили, что вы это делали.

Вы можете использовать несколько большие значения (за счет невозможности сохранения отрицательных значений) с использованием типа unsigned long long, который имеет минимальное значение 0 и максимум не менее 2 64 -1, или 18 446 744 073 709 551 615, приблизительно 1,8 * 10 19.

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

  • 0
    Хорошее объяснение.
  • 0
    @KeithThompson: Да, я знаю, что значение больше 10 ^ 18 будет переполнено. но когда я ввожу значение больше 10 ^ 18 с выводом scanf, это либо да, либо нет, тогда как, когда я использую cin >>, он печатает и да, и нет вместе. Кроме того, когда я отправил этот код с помощью cin >> on, SPOJ получил неправильный ответ, но с помощью scanf () получил AC (с тем же кодом). Вы даже можете проверить это на SPOJ.
Показать ещё 1 комментарий
2

Например, вы пытались протестировать небольшие числа, например, 5? Если он работает, возможно, что-то в номере, который вы вводите, который, вероятно, не в максимуме, который может содержать long long int. Просто попробуйте сделать это в своей системе:

#include <iostream>
#include <stdio.h>
#include <limits>
using namespace std;

int main()
{
std::cout << std::numeric_limits<long long int>::max() << std::endl;
return 0;
}

и проверьте, больше ли введенное вами значение, чем напечатанное. Если это так, просто объявите переменную с достаточным пространством для значения, если значение напечатано выше введенного значения и там STILL ошибка, прокомментируйте эту запись.

  • 0
    По сути, я получаю правильный ответ для небольших значений. Но когда я ввожу значение больше 10 ^ 18 с выводом scanf, это либо да, либо нет, тогда как, когда я использую cin >>, тогда он печатает и да, и нет вместе. Почему этот странный вывод и в чем разница, что один принимается, а другой дает неправильный ответ.
  • 0
    @AmitTripathi Точно 10 ^ 18? Мол, 10 ^ 18 работает, а (10 ^ 18) +1 нет? Scanf может вызвать переполнение буфера, поэтому возможно, что он сохранил введенное число даже за пределами границы переменной long long в памяти. Что печатает код, который я упоминал выше?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню