Hi,

I am having some problems at times with converting to double and taking the square root.
Sometimes it works and sometimes it does not and I am not sure why!

I am adding the sum of the square root of 10 numbers for each of 50 rows into an array.
Then I am adding all the sum of the 50 rows into a variable.

It seems to only work when I add the sum of the 10 numbers and then take the square root of the sum for each of the 50 rows, but when I try to add the sum of the square root of 10 numbers for each of the 50 rows I get the wrong results???

Can anyone help?

Here is my code:

for (liAddRowPos= 1; liAddRowPos <= 50; liAddRowPos++)
        {


                aGV.gaElementSymmetry_Sum[liAddRowPos, 1] = 0;

                aGV.gaElementSymmetry_Sum_SQRT[liAddRowPos, 1] = 0.0;


                for (liMiscLp = 1; liMiscLp <= 10; liMiscLp++) aGV.gaElementSymmetry_Sum[liAddRowPos, 1] += aGV.gaElementSymmetry[liAddRowPos, liMiscLp];



                for (liMiscLp = 1; liMiscLp <= 10; liMiscLp++) aGV.gaElementSymmetry_Sum_SQRT[liAddRowPos, 1] += Convert.ToDouble(Math.Sqrt(aGV.gaElementSymmetry[liAddRowPos, liMiscLp]));


        }



        aGV.giGrandTotal = 0.0;

        aGV.giGrandTotal_SQRT = 0.0;



        for (liAddRowPos= 1; liAddRowPos <= 50; liAddRowPos++)
        {


                aGV.giGrandTotal += Convert.ToDouble(Math.Sqrt(aGV.gaElementSymmetry_Sum[liAddRowPos, 1]));


                aGV.giGrandTotal_SQRT += Convert.ToDouble(Math.Sqrt(aGV.gaElementSymmetry_Sum_SQRT[liAddRowPos, 1]));


        }

An answer would be greatly appreciated.

Thanks
Roy

Recommended Answers

All 13 Replies

Doubles are not "exact" numbers. You are confronted with rounding errors.
Try this: It will not give you what you expected:

double d = 0.0;
for (int i = 0; i < 100000; i++)
    {
        d = d + 1000000.23;
    }
    MessageBox.Show(d.ToString());

Using Double numbers can be quite unpredictable. Try using the Math.Round() function to round off your results before adding them together.

Using Double numbers can be quite unpredictable. Try using the Math.Round() function to round off your results before adding them together.

Hi James,

How many numbers should I round it off to in order to be 100% sure that there won't be any rounding errors? Is 6 ok? Or is it impossible to be 100% sure that there won't be any rounding errors regardless of how many numbers it is rounded off to?

Actually, what is more important to me than the rounding errors is whether it does it consistently! That is I am not worried if the actual value that is derived is not 100% right, what is important is that it will produce the same value (albeit wrong) every time it is processed?

For example, if I am adding the sum of the square root of these 10 numbers:

2,7,9,12,18,21,28,33,39,47

will it produce the same result regardless if the answer is not 100% correct every time?

Thanks
Roy

You can never be certain of rounding errors. For instance try running the following code:

Console.WriteLine("{0:G17}", 0.72 + 0.11 + 0.06 + 0.11);

On my system, this returns 0.99999999999999989. Note that this may be different for your system, which leads to your second question. Consistency cannot be guaranteed across different architectures. It should produce consistent results on the same machine, but I cannot say that with certainty.

Member Avatar for stbuchok

Do you have to use double? Can you use decimal?

Someone correct me if I'm wrong but I believe this issue won't happen for Decimal.

I believe decimal numbers just provide more significant digits than double or float.

Right stbuchok, the decimal type was specially designed to avoid rounding errors for numbers and is most often used in the banking world. But then again I guess in Wall Street they mostly do percentage calculations and no square roots.

I get the same result 0.99999999999999989!

It is really too bad that it cannot be ascertained 100% all the time as I was counting on it.

You see my dilemma is that I have to save this information, that is 50 rows by 10 columns for each object that I have and unfortunately I have millions upon millions of objects to save and to compare and in the future these numbers will grow even more.

I was hoping that instead of saving 50 x 10 (500 integers) I could get away with saving only 1 double variable using the sum of the square root of the numbers because if any of the 500 numbers is different then that would produce a different double variable value using the sum of the square roots.

Roy

I thought of using whole numbers using exponents such as the power of 2, but the numbers get very large very fast.

I guess I could use decimal but I have never used it. Do you mean though that if I used decimal instead of double I would not be encountering any of these problems 100%?

Member Avatar for stbuchok

Try it out and let us know.

BTW, is it absolutely necessary to use a square root?
I'm thinking of a sum or a mean.

Hi,

I think that I am going to use the sum of the squares rather than the sum of the square roots. In retrospect, it is probably better to use the sum of the squares because usually it needs a lot less precision than the square root. For example, the square of 8 is 64 but the square root of 8 is 2.828427125. Furthermore, because in the future I will be adding more numbers and bigger numbers I have circumvented the problem of adding all the numbers which could get quite large by oscillating between adding and substracting the square root of the numbers. In other words, I add the first number then substract the second then add the third then substract the fourth and so on...

In the future I will probably use long instead of int so that gives me more room. By the way I have heard about the BigInteger variable but it does not seem to be part of of Visual Studio 2010 Express Edition. I read that it is part of .NET 4.0 but I do not know which .NET version VS 2010 Express is? Does anyone know?
Will they include it in the future?

Thanks Everybody for your help I really appreciate it. :)

Roy

try this code hope it will work fine

double value = 0.0;
for (int j = 0; i <20; j++)
{
       value = value + 500.23;
}
MessageBox.Show("your required inforamtion"value.ToString());
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.