Переполнение в результате выполнения арифметической операции как исправить

Bill Gates

7 / 7 / 3

Регистрация: 25.11.2010

Сообщений: 93

1

Переполнение в результате выполнения арифметической операции

22.04.2011, 21:21. Показов 27784. Ответов 5

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

При использовании типа int — ошибки нет,
но некоторым переменным необходимо присвоить значения более 1000 000 000
Поэтому для переменной frmGeneration.QuantityOfVectors я задал тип ulong

В результате возникла ошибка в строке:

C#
1
values = new string[frmGeneration.QuantityOfVectors];

«Переполнение в результате выполнения арифметической операции»

И progressBar пришлось отключить, т.к. в

C#
1
pBarGeneration.Maximum =frmGeneration.QuantityOfVectors;

несоответствие типов int и uint.

Как можно это исправить?



0



36 / 36 / 8

Регистрация: 10.02.2010

Сообщений: 184

23.04.2011, 05:30

2

Про трэк бар всё довольно просто…Используй pBarGeneration.Maximum=frmGeneration.QuantityOfVectors/N, где N — множитель….И через каждые N шагов, значение прогресбара увеличивай на 1.

На счёт больших чисел, напиши лучше класс, или поищи уже готовые решения для этого…Длинная арифметика называется



1



4335 / 1504 / 101

Регистрация: 12.04.2009

Сообщений: 2,342

23.04.2011, 10:27

3

1000 000 000 указателей по 4 байта = 4000000000 байт = 3906250 Кб = 3814 Мб = 3.7 Гб



2



nicolas2008

1113 / 827 / 258

Регистрация: 30.04.2009

Сообщений: 3,453

23.04.2011, 10:41

4

Что то я сомневаюсь в адекватности работы программы…
Не знаю предметной области, но предполагаю, что это

C#
1
values = new string[frmGeneration.QuantityOfVectors];

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



1



Bill Gates

7 / 7 / 3

Регистрация: 25.11.2010

Сообщений: 93

23.04.2011, 12:29

 [ТС]

5

1000 000 000 указателей по 4 байта = 4000000000 байт = 3906250 Кб = 3814 Мб = 3.7 Гб

Как же мне быть — мне все равно нужно использовать такие значения и даже больше?
Можете объяснить подробнее — я не понимаю в чем заключается ошибка.

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

Каким образом можно это сделать?
Вы же понимаете, как трудно писать свой первый проект.
Первый блин комом.
Не поможете ли новичку?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
unsafe  private void lfsr()
        {
            pBarGeneration.Minimum = 1;
         pBarGeneration.Maximum =frmGeneration.QuantityOfVectors;
            pBarGeneration.Step = 1;
 
            values = new string[frmGeneration.QuantityOfVectors];
                    
            values[0] = frmInItialStatus.statusTemporaryString;
 
            for (ulong j = 1; j < frmGeneration.QuantityOfVectors; j++)
            {           
                 
                if (j < FirstVector)
                {
                  int*  sA= _lfsr(frmInitGen.DimentionOfGenerator, frmInputPolynom.polynomArray, frmInItialStatus.statusArray);
                    pBarGeneration.PerformStep();
                }
                else
                {
                    int* sA = _lfsr(frmInitGen.DimentionOfGenerator, frmInputPolynom.polynomArray, frmInItialStatus.statusArray);
                    string s = "";
                    for (int i = 0; i < frmInItialStatus.statusArray.Length; i++)
                    {
                        
                      s += sA[i];
                    }
                    values[j] = s;
                    pBarGeneration.PerformStep();
 
                  
                }



0



1113 / 827 / 258

Регистрация: 30.04.2009

Сообщений: 3,453

23.04.2011, 13:22

6

Вместо создания такого массива пишите в текстовый файл — медленнее, но точно памяти хватит.
Оптимально писать не по одной строчке, а по несколько, например по 5000.
то есть у вас будет массив values=new string[5000], при прохождении по циклу вы его заполняете аналогично как сейчас, только еще будет индекс текущей строки в массиве values. Когда массив заполнился — записывайте его в файл, и снова заполняете его сначала, и так до конца цикла.



1



  • Remove From My Forums

 none

Дополнительные сведения: Переполнение в результате выполнения арифметической операции.

  • Вопрос

  • Public Shared Sub encXORPass(ByVal da() As Byte, ByVal offset As Integer, ByVal size As Integer, ByVal key As Integer)
    			Dim [stop] As Integer = size - 8
    			Dim pos As Integer = 4 + offset
    			Dim dx As Integer
    			Dim cx As Integer = key
     
    			Do While pos < [stop]
                    dx = (da(pos) And &HFF)
    				dx = dx Or (da(pos + 1) And &HFF) << 8
    				dx = dx Or (da(pos + 2) And &HFF) << 16
    				dx = dx Or (da(pos + 3) And &HFF) << 24
     
                    cx += dx
     
    				dx = dx Xor cx
     
                    da(pos) = CByte(dx And &HFF)
    				pos += 1
    				da(pos) = CByte(dx >> 8 And &HFF)
    				pos += 1
    				da(pos) = CByte(dx >> 16 And &HFF)
    				pos += 1
    				da(pos) = CByte(dx >> 24 And &HFF)
    				pos += 1
    			Loop
     
    			da(pos) = CByte(cx And &HFF)
    			pos += 1
    			da(pos) = CByte(cx >> 8 And &HFF)
    			pos += 1
    			da(pos) = CByte(cx >> 16 And &HFF)
    			pos += 1
    			da(pos) = CByte(cx >> 24 And &HFF)
                pos += 1
     
            End Sub
    Code: C#

    И вот тут cx += dx идет Переполнение в результата!! Помогите пожалуйста, уже 3 день не могу понять в
    чем проблема, что не так(((( это грубо говоря ключ ш
    ифрации Blowfish!!

Ответы

  • Добрый день.

    У меня есть подозрение, что у вас в результате сдвигов получаются очень большие числа. Поставьте точку останова и посмотрите, что там происходит.

    • Помечено в качестве ответа

      29 сентября 2013 г. 15:41

  • Один топик, один вопрос. Так потом проще по форуму искать.

    Сейчас же у вас, идет попытка доступа к объектной переменной, в которой храниться null. Поставьте на входе в метод на который вы грешите
    Assert-ы и посмотрите, что там происходит.

    • Помечено в качестве ответа
      xLargoWinch
      29 сентября 2013 г. 15:07

The expression (ulong)arr.Sum() is invoking Enumerable.Sum<int>(), which performs the summation using the int data type, then casts the result to ulong. This means that the result must be in the domain of the int data type to avoid overflow, but it is not.

You can resolve this a number of ways. Perhaps the easiest would be to cast the numbers to ulong before summing, but then you have to deal with the fact that there is no Enumerable.Sum() overload that accepts ulong.

Not to worry; we can just use Enumerable.Aggregate() to define the operation ourselves:

ulong sum = arr
    .Select(i => (ulong)i)       // Convert elements to ulong
    .Aggregate((a, b) => a + b); // Sum

You could also parse the numbers as ulongs instead of ints:

ulong[] arr = Array.ConvertAll(arr_temp, ulong.Parse);

ulong sum = arr.Aggregate((a, b) => a + b);

Note that there is an Enumerable.Sum() overload for the long data type, so you could consider using that instead.

d

Оператор checked применяется для проверки на переполнение, которое возникает при выполнении арифметических действий с целочисленными значениями.
Если в блоке checked происходит переполнение, то вызывается исключение.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

    using System;

    class One {

     byte a = 254;

     byte b;

     public One(byte arg) {

      b = arg;

     }

     public void Result() {

      checked {

       Console.WriteLine(«{0} + {1} = {2}», a, b, ((byte)(a + b)));

      }

     }

    }

    class Program {

     public static int Main() {

      Console.Write(«введите число : «);

      byte val = byte.Parse(Console.ReadLine());

      One O = new One(val);

      O.Result();

      Console.ReadKey();

      return 0;

     }

    }

введите число : 2

Необработанное исключение: System.OverflowException: Переполнение в результате выполнения арифметической операции.

в One.Result() в d:projectnewCSharpConsole0001Main.cs:строка 11

в Program.Main() в d:projectnewCSharpConsole0001Main.cs:строка 21

Для продолжения нажмите любую клавишу . . .

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

    using System;

    class One {

     byte a = 254;

     byte b;

     public One(byte arg) {

      b = arg;

     }

     public void Result1() {

      //если произойдет переполнение, то исключение вызвано не будет

      unchecked {

       Console.WriteLine(«{0} + {1} = {2}», a, b, ((byte)(a + b)));

      }

     }

     public void Result2() {

      //то же самое без оператора unchecked

      Console.WriteLine(«{0} + {1} = {2}», a, b, ((byte)(a + b)));

     }

    }

    class Program {

     public static int Main() {

      Console.Write(«введите число : «);

      byte val = byte.Parse(Console.ReadLine());

      One O = new One(val);

      O.Result1();

      O.Result2();

      Console.ReadKey();

      return 0;

     }

    }

введите число : 2

254 + 2 = 0

254 + 2 = 0

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Pick a username
Email Address
Password

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Понравилась статья? Поделить с друзьями:
  • Как исправить слоеное тесто если оно жесткое
  • Как лучше найти работников
  • Как найти raspberry в сети
  • Как найти клиентов на печать
  • Как составить жалобу в надзор