Reputation: 15
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
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