Tyler Miles
Tyler Miles

Reputation: 15

I need exact value but my integer variable overflows

I need to do divide the number which equals to sum of some big values. But after a while, it overflows and it equals to a negative number. I tried to use BigInteger,decimal and double but it doesn't work again.

Error message:System.ArgumentException 'Value of '256' is not valid for 'red'. 'red' should be greater than or equal to 0 and less than or equal to 255.'

Edit: When i checked value of GaussFiltresi[syc] i have seen that :'GaussFiltresi[syc]' threw an exception of type 'System.IndexOutOfRangeException'

#region Gaussian Filter

public void gaussianfilter (int SablonBoyutu,Bitmap GirisResmi,Bitmap CikisResmi)
{
int ResimGenisligi = GirisResmi.Width;
int ResimYuksekligi = GirisResmi.Height;
int syc = 0;
BigInteger toplamR;
BigInteger filtrekatsayitoplami; 
BigInteger ortalamaR;
int kernelsinir = ((SablonBoyutu - 1) / 2); 
for ( i = -kernelsinir; i <= kernelsinir; i++)
{
 for ( j = -kernelsinir; j <= kernelsinir; j++)
  {
  //some calculations
  }
}

for (int x = (kernelsinir); x < ResimGenisligi - kernelsinir; x++)
{
 for (int z = (kernelsinir); z < ResimGenisligi - kernelsinir; z++)
 {
  syc = 0;
  toplamR = 0;
  for (int y = -(kernelsinir); y <= kernelsinir; y++) 
   {
    for (int d = -(kernelsinir); d <= kernelsinir; d++)
    {
    OkunanRenk = GirisResmi.GetPixel(x + y, d + z);
    toplamR += GaussFiltresi[syc] * (BigInteger)(OkunanRenk.R);
    //toplam R=1662424090 and GaussFiltresi[syc] = 5389698 before overflowing
     syc++;
    }
   }
ortalamaR = toplamR / filtrekatsayitoplami; //toplamR is negative 
CikisResmi.SetPixel(x, z, Color.FromArgb((int)ortalamaR, (int)ortalamaR,(int)ortalamaR));
  }
 }
}

        #endregion

Upvotes: 0

Views: 110

Answers (1)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 62012

With a reference to System.Numerics.dll, you can use BigInteger instead of Int64 (a.k.a. long).

Another option is to use double that does not overflow (to PositiveInfinity) before 10**308, or 1e+308. Or decimal that goes to more than 1e+28m.

Update after comments: Your expression:

GaussFiltresi[syc] * OkunanRenk.R

is an int times an int. In fact becomes 14650719 * 160, which gives -1950852256. To have the two operands promoted to BigInteger, such that the multiplication * will be multiplication of big-ints (that never overflow), cast either operand to BigInteger (the other will be promoted to BigInteger for free), just as I said in my comment:

GaussFiltresi[syc] * (BigInteger)(OkunanRenk.R)

so the entire statement becomes:

toplamR += GaussFiltresi[syc] * (BigInteger)(OkunanRenk.R);

A multiplication of an int by an int will be done as an int multiplication (and the result may "wrap around"). It is not changed by the fact that the result is going to be +=-ed to a BigInteger later. That was the reason why it did not work after your initial code changes.

Upvotes: 3

Related Questions