1. ## C# calculation problem

I was wandering if someone could tell me how I could make c# do a round off for 1/3 or 2/3 before placing it into a calculation.

For example:
I know that c# is terrible with 1/3 and 2/3 and will output an incorrect value if put into an equation... (Ex. (a * (2/3) * (2/3))+(b*(1/3)+c)) cause i have tested..
So, i decided that since 1/3 and 2/3 are infinite decimals (0.333...and so on) i was wandering if someone could tell me how to tell c# to round off 1/3 or 2/3 (0.33) before putting it into the calculation.

Any ideas?

2. I suspect that the problem has more to do with 2/3 being integer divide -> zero.

If you make it 2.0/3.0, (etc) does it perhaps work better?

--
Mats

3. C# is perfectly correct in the equation. It just happens to use strict integer arithmetic.

4. no no...
This is what i get, ' 4.44089209850063E-16 ' if calculated with 2/3.. Which is utterly wrong... Any other number works perfectly fine and the problem only stays with 1/3 or 2/3. I have checked my equation several times and theres nothing wrong with it.... Done it on paper even to confirm - other numbers work perfectly but 1/3 or 2/3 don't work.

Thats why i'm asking if there is a way to round off to a few decimal spaces before calculating.

btw: I'm using 'double' for all my variables.

5. Can you post a full compilable example? That'll pop my C# cherry - I have the Visual Studio installed, but I've never compiled a single line of C# - got to be a first some time tho'.

--
Mats

6. Code:
```using System;
using System.Collections.Generic;
using System.Text;

namespace Factoring_2
{
class Program
{

static void Main(string[] args)
{
Console.WriteLine("ax˛ + bx + c");
Console.WriteLine("Enter value a");
double a = Convert.ToDouble(sa);
Console.WriteLine("Enter value b");
double b = Convert.ToDouble(sb);
Console.WriteLine("Enter value c");
double c = Convert.ToDouble(sc);

double[] narray = new double[100];
double[] darray = new double[100];
double[] frac = new double[100];

double ab, nab, bc, nbc = 0;

if (c > 0)
{
for (int i = 1; i <= c; i++)
{

narray[i] = (a * (i * -1) * (i * -1)) + (b * (i * -1)) + c;
darray[i] = (a * i * i) + (b * i) + c;

if (narray[i] == 0)
{
Console.WriteLine("One of the factor is:");
Console.WriteLine("x + " + i);
nab = ((a * (i*-1)) + b);
nbc = ((nab * (i*-1)) + c);

if (nbc == 0)
{
Console.WriteLine("The other factor is:");
Console.WriteLine(a + "x + " + nab);
break;
}
}

if (narray[i] != 0 )
{
for (int x = 2; x <= 10; x++)
{

for (int y = 1; y <= x; y++)
{
narray[y]= 0;
frac[y] = (double)y / (double)x;
narray[y] = (a * (frac[y] * frac[y])) + (b * (frac[y] * -1)) + c;

Console.WriteLine("y = "+ y + "  /  " + "x = "+ x+"  = " + narray[y]);

if (narray[y] == 0)
{
Console.WriteLine("One of the factor is:");
Console.WriteLine(x+"x + " + y);

}
}

}

}

if (darray[i] == 0)
{
Console.WriteLine("One of the factor is:");
Console.WriteLine("x - " + i);
ab = ((a * i)) + b;
bc = ((ab * i)) + c;

if (bc == 0)
{
Console.WriteLine("The other factor is:");
Console.WriteLine(a + "x - " + ab);
break;
}
}
if (darray[i] != 0)
{
for (int x = 1; x <= 10; x++)
{
for (int y = 1; y <= x; y++)
{
frac[y] = (double)y / (double)x;
darray[y] = a * (frac[y] * (frac[y])) + (b * (frac[y])) + c;
if (darray[y] == 0)
{
Console.WriteLine("One of the factor is:");
Console.WriteLine(x+"x - " + y);
break;
}
}
}
}

}
}```
ok, well heres the code... i want you to look for yourself and put these numbers in after you run the program:
a = 6
b= 7
c= 2
correct output: (2x+1)(3x+2)
In this line:
Console.WriteLine("y = "+ y + " / " + "x = "+ x+" = " + narray[y]);
is basically supposed to output the calculation and you will see that the answer for 2/3 is incorrect, but all the rest numbers are correct.

7. What do you think the result should be if you calculate:
2.6666666666666665 + -4.6666666666666661 + 2.0

Those are the partial results from your calculation:
narray[y] = (a * (frac[y] * frac[y])) + (b * (frac[y] * -1)) + c;

I find that the result should be zero - but because of rounding errors, you get a "very small number" - this is perfectly normal when using floating point calculations, especially subtracting or adding the result of other calculations.

Remember, floating point (double or float) calculations are approximations - not exact results.

Edit: I'm pretty sure it's more efficient to use -frac[y] instead of frac[y] * -1...

--
Mats

8. Meh, just a case of floating point inaccuracy. The value you're getting is merely 2*epsilon. That is, it's the second-closest-to-0 number that a double can represent that is not 0 itself.

So, not strict integer arithmetic, but loose floating point arithmetic.

9. hmm... So what should i do? Is there a way to round it off?
if not .. then could i have c# read that as 0 by adding an if statement?

10. You could do your comparisons as
Code:
`if(Math.abs(f) < EPSILON)`
where EPSILON is a sufficiently small number.

As for the output, use formatted outputting instead of string concatenation and force normal display of floats instead of scientific, then the rounding is done automatically.

11. hmmm .. doesn't work ..
Ive tried using:
if (narray[y] == ((a * ((2 / 3) * (2 / 3))) + (b * ((2 / 3) * -1)) + c))
but didn't work .. why not? It should output the exact same value shouldn't it? Apparently it outputs the answer of 2 .... ???

12. Originally Posted by Diablo02
hmmm .. doesn't work ..
Ive tried using:
if (narray[y] == ((a * ((2 / 3) * (2 / 3))) + (b * ((2 / 3) * -1)) + c))
but didn't work .. why not? It should output the exact same value shouldn't it? Apparently it outputs the answer of 2 .... ???
That _IS_ because 2/3 turns into zero, because it's an integer - I'm pretty sure of that - and in your example, c is 2, so that'll be your answer in this case.

Try using 2.0 and 3.0 instead of 2 and 3.

Edit: and just to clarify, this would give a very similar result to your calculation using frac[y] as indicated above - it doesn't change the math operations going on inside the processor, and they are by definition inprecise.

--
Mats

13. Originally Posted by matsp
Try using 2.0 and 3.0 instead of 2 and 3.
Hmm, thats better, thanks

14. Why not use a regular expression to trim off the extra points, or specify your precision ( er, wait - can you specify precision? :| I don't use C# enough to remember ... lol? )

* edit *

My pre-response in regard to using regexps & potential inefficiency/bloat: Precision comes at a cost, of course.