kavinderrana121 Ответов: 3

Целочисленное переполнение в приведенной ниже программе


Я решал проблему на spoj,SPOJ.com - проблема в минуту!!![^]
Проблема проста,и я получаю правильный вывод для небольших чисел, но, похоже, spoj не принимает из-за переполнения целых чисел ,
Тогда какой целочисленный тип я должен использовать?

Или есть какая-то другая проблема, которую они не принимают ?Я также не знаю тестовых случаев, в которых он может потерпеть неудачу

Один из принятых решений других парней, которые используют ту же логику, и его решение принимается SPOJ кресла – карты | учебники хор [^]





Тестовый пример:

2
3
7
выход:

15
77

Что я уже пробовал:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        unsigned long long int sum1=0;
        unsigned long long int sum2=0;
        sum1=((n*(n-1))/2)%1000007;
      //  cout<<"sum1 is"<<sum1;
        sum2=(n*n+n)%1000007;
        cout<<(sum1+sum2)%1000007<<endl;

    }

}

3 Ответов

Рейтинг:
2

#realJSOP

0) я не знаком с типом, который вы используете - unsigned long long int.

1) переменные n, sum1, и sum2 должен ВСЕ быть ulong значения (или, по крайней мере, все тот же целочисленный тип).

2) Вы говорите, что это не удается, когда вы используете "большие числа". В каком смысле он "проваливается"?

3) Поскольку вы занимаетесь математикой, я бы подумал об использовании decimal в твоем вкусе.


kavinderrana121

Он принимается, когда я использую unsigned long long n, но почему это произошло ? поскольку максимальное значение int было дано 1 000 000, значит, оно также должно быть принято и на int?

#realJSOP

Все целочисленные типы одинаковые (без знака длинный). Вы также не сказали, что такое исключение. В качестве теста я сделал н int, и ушел sum1 и sum1 как и неподписанные лонги, И.Сеть выбросила исключение, потому что н не хочу долго оставаться без подписи.

Рейтинг:
2

Patrice T

Цитата:
Целочисленное переполнение в приведенной ниже программе

Используйте отладчик, чтобы точно видеть, что происходит в вашем коде, и видеть, где происходит переполнение.

Ваш код ведет себя не так, как вы ожидаете, или вы не понимаете, почему !

Существует почти универсальное решение: запускайте свой код на отладчике шаг за шагом, проверяйте переменные.
Отладчик здесь, чтобы показать вам, что делает ваш код, и ваша задача-сравнить с тем, что он должен делать.
В отладчике нет никакой магии, он не знает, что должен делать ваш код, он не находит ошибок, он просто помогает вам, показывая, что происходит. Когда код не делает того, что ожидается, вы близки к ошибке.
Чтобы увидеть, что делает ваш код: просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик - Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010 - YouTube[^]

1.11 — отладка программы (пошаговое выполнение и останова) | выучить C++[^]

Отладчик здесь только для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.


Рейтинг:
0

CPallini

Ваш код использует правильный тип данных на неправильной стороне назначений. Например в

Цитата:
sum1=((n*(n-1))/2)%1000007;
sum1 может быть (32-битным) int так как его вычисленные значения всегда меньше чем 1000007.

С другой стороны, ((n*(n-1))/2)%1000007 должно быть написано вместо этого
((unsigned long long)n*(n-1))/2)%1000007
для того чтобы принудить правильную оценку, т. е. без переполнения n*(n-1) Явное приведение необходимо (вы можете использовать C++ static_cast, если хотите), потому что в противном случае все выражение является первый оценено с помощью int операнды и затем результат (переполненный) повышается до unsigned long long.