C++ outputs "x" as an integer.

Hi, so I recently started learning C++ and I first decided to make a quadratic calculator. I have seen through some of the errors and I eventually cleared them up, and I thought it was perfect so tried it out. It worked perfectly for the equations that I tried out. Except when I tried out "x^2 + 3x + 3", the output comes as " 1 + 0.866025i" and "1 - 0.866025i", even though its suppose to be "1.5 + 0.866025i" and "1.5 - 0.866025i". I set x as a float type so I don't see why x outputs as an integer. Here's my code.

#include <iostream>
#include <cmath>
#include <math.h>
#include <stdio.h>
using namespace std;

int main()
{{
int a , b , c;
float xi , x;
char response , Y , N;

do {
cout << "Equation format is ax^2 + bx +c" << endl;
cout << "Input value of a\n" , cin >> a;
cout << "Input value of b\n" , cin >> b;
cout << "Input value of c\n" , cin >> c;

if ( a == 1 ) {

cout << "x^2 + " << b << "x + " << c << " = 0" << endl;

}
else cout << a << "x^2 + " << b << "x + " << c << " = 0" << endl;

cout << "Is this correct, (Y/N)?\n" , cin >> response;
}
while ( response != 'Y' );

x = b * b - 4 * a * c;

if ( x == 0 ) {

x = - b / (2 * a);

cout << "x = " << x << endl;

return 0;
}

else if ( x > 0 ) {

x = (- b - pow( ( b * b ) - 4 * a * c , (0.5)))/ ( 2 * a );

cout << "x = " << x << endl;

cout << "or" << endl;

x = ( - b + pow( ( b * b ) - 4 * a * c , (0.5)))/ ( 2 * a );

cout << "x = " << x << endl;

return 0;
}

else if ( x < 0 )

x = ( - b / 2 * a );
xi = ( pow(( 4 * a * c - ( b * b ) ) , (0.5))) / ( 2 * a );

if ( xi == 1 ){


cout << "x = " << x << " + " << "i" << endl;

cout << "or" << endl;

cout << "x = " << x << " - " << "i" << endl;
}

else {

cout << "x = " << x << " + " << xi << "i" << endl;

cout << "or" << endl;

cout << "x = " << x << " - " << xi << "i" << endl;
}}

return 0;
}
I can only guess that pow( ( b * b ) - 4 * a * c , (0.5)) is an integer value. You could explicitly convert the first argument to double.
Or just make a, b, and c floats. Why did you make them integer, anyway?
pow( ( b * b ) - 4 * a * c , (0.5) is sometimes an integer and other times a float. It outputs as a float type during other calculations though...I mean 0.866025 is also from there.

I tried with double, I got the same results tbh.
I started writing the program with "int" and by the end I did not see any point in making them floats since I am always going to input the values and they will be integers.
By "integer value" I meant a value of integer type, not a value of float type that happens to mathematically be an integer.
1L is an integer value
1.f is a float value, and also mathematically an integer

I see what you mean, and I agree that it's weird that xi = ( pow(( 4 * a * c - ( b * b ) ) , (0.5))) / ( 2 * a ) does evaluate to a float, while this seems to evaluate to an int. I have no explanation.
#include <cmath>
#include <math.h> //remove this it is the C version of the above one(ironically, the one with C in it is the c++ one).

you could probably work around the issue in 2 simple ways:
use the complex<double> template to handle the imaginary answers and/or
use sqrt instead of pow to the 1/2 may resolve it.

x is computed as an integer.

x = ( - b / 2 * a );

b/2 is integer math. this should be b/2.0

Looking for similar mistakes elsewhere. I think the rest are ok but you may want to put 2.0 on the power computations as well. Standard Pow should always result in a double or long double. This one: / ( 2 * a ); I can't tell if it has a negative effect or not, but be safe, make them 2.0.

doing this (and accepting lower case for 'y', a recommended upgrade), I get:

----------------------------------------
Input value of a
1
Input value of b
3
Input value of c
3
x^2 + 3x + 3 = 0
Is this correct, (Y/N)?
y
x = -1.5 + 0.866025i
or
x = -1.5 - 0.866025i



Last edited on
I followed helios's advice and let a,b,c = float which...actually ended up working. I have no clue what a,b,c have to do with the final value of x but...it works so thanks.

and jonnin, being a beginner I still don't know how to use the complex<double>thats why I used....what you see basically. And I was considering keeping "y" as an acceptable answer, but that would be later since those are small stuff.

Is there anyway to keep root in the final output though? Like, my program displays "-1.5 + 0/866025i" but could I get it to "1.5 + √3/2"?
I have no clue what a,b,c have to do with the final value of x but...it works so thanks.

Well, you ought to understand what you're doing if you're going to be doing it at all. Clearly, the roots of a quadratic equation depend ax2 + bx + c = 0.
The reason they need to be floats as opposed to integers is to do float division instead of integer division by default (and apparently some weird behavior with pow).

Is there anyway to keep root in the final output though?

Don't take the square root (pow ^ 0.5) in your calculations, simply leave the radicand alone.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

int main()
{
    double a = 1.0;
    double b = 3.0;
    double c = 3.0;

    // real part:
    double xr = -b / (2 * a);

    // imaginary part:
    double radicand = 4 * a * c - b * b;
    double denom = 2 * a;

    std::cout << xr << " + √(" << radicand << ")/" << denom << "\n";
}


https://ideone.com/H5kIlM
-1.5 + √(3)/2
Last edited on
I have no clue what a,b,c have to do with the final value of x
What do you mean you have no clue? Is the value of x independent of the values of a, b, and c? Surely you know that ((int)1)/2 is a value and type strictly different from ((double)1)/2. Then it should be unsurprising that changing the types involved changes the value of the result.
@Ganado, by printing "√radicand" I remove the possibility of rooting values like "9" to "3" or "24" to "2√6". And by printing the denom seperately, I cant divide the equation by it, even if it is divsible.

@Helios I meant that the relationship between the data type of a,b,c and x. a,b,c were integers, but x was a float. So even if some calculation involving a,b,c led to a non-integer, as long as x is equal to that value, x should have displayed it being a float. And as I mentioned, I'm new. Its barely been a week since I started. So its still surprising to me.
Then add logic to not print the radicand if it's a perfect square.

Shamelessly copied from SO
https://stackoverflow.com/questions/1549941/perfect-square-and-perfect-cube
1
2
3
4
5
6
bool is_perfect_square(int n) {
    if (n < 0)
        return false;
    int root(round(sqrt(n)));
    return n == root * root;
}


If you want to have sqrt(24) be output as 2 * sqrt(6), you have to program that logic yourself too -- You'd have to find the number's prime factorization (24 = 2 * 2 * 2 * 3), and if there's a 2x repetition of numbers, factor those out. It's kinda complicated for a beginner, but certainly possible. C++ doesn't know symbolic computation, it isn't Mathematica.
Last edited on
"√24" to "2√6" isn't a perfect square. How do I do that then?
See my edit.

Find prime factorization of 24 = 2 * 2 * 2 * 3.
Every time there's 2x of the same number (e.g. the 2 * 2), factor it outside. With the remaining numbers, repeat the factoring process until there are no more squares (2 * 3). This will require making an array or list of numbers, which I'm not sure if you've learned yet.

If you're just a beginner, I seriously wouldn't worry about outputting correct symbolic notation.

Edit: Apparently there's different methods than finding the prime factorization, see https://castingoutnines.wordpress.com/2008/02/07/the-illini-method-for-simplifying-a-radical/

_______________________________________

Edit 2: So, instead of doing the prime factorization, you just need to check every square number below the sqrt(number) you're trying to simplify, to see if you're divisible by that number. If so, factor it out.
For example, 24. The square numbers below 24 are: 4, 9, 16.
Is 24 divisible by 16 --> no
Is 24 divisible by 9 --> no
Is 24 divisible by 4 --> yes! divide by 4 on the inside, multiple by sqrt(4) = 2 on the outside.
repeat process with 24 / 4 = 6 until there are no square divisible numbers under your number.

Sorry rushed because I have to leave for something, otherwise I'd totally just program this myself.
Last edited on
Yeah, no haven't learned that yet. I wouldn't say "worry", I just want it to be decent. Anyway I'll look into your suggestion, thanks.
I meant that the relationship between the data type of a,b,c and x. a,b,c were integers, but x was a float. So even if some calculation involving a,b,c led to a non-integer, as long as x is equal to that value, x should have displayed it being a float.
No.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int a1 = 1;
int a2 = 2;
float b1 = 1;
float b2 = 2;

int   int_to_int     = a1 / a2;
float int_to_float   = a1 / a2;
int   float_to_int   = b1 / b2;
float float_to_float = b1 / b2;

std::cout
    << int_to_int << std::endl
    << int_to_float << std::endl
    << float_to_int << std::endl
    << float_to_float << std::endl;
0
0
0
0.5

Simply put, you can't get 2 liters out of a 1 liter bucket, and if you pour 2 liters into a 1 liter bucket, the extra liter will spill out.
Even if you start with precise data, if it passes at any point through a less-precise representation you won't get the precision back by converting the now-imprecise data to a more-precise representation.
Last edited on
FYI what was happening that I fixed with the 2.0s was that internally you were losing precision down to integer levels. The results were floating point values technically, but you had done integer math that lost information before it converted to floating point, leaving the result as an integer in many cases.

c++ has sqrt and cbrt (I think, I don't use it much) for square root and cube root. Anything else needs power function I think.

I am not really sure what you are going on about with the square roots but there are only 3 or 4 sensible ways to do them.
1) sqrt of everything, eg √(26)
2) decimal everything, eg 5.09902
3) alternatives of the above, eg 26^0.5
4) mixed. 26 is a bad example, but say, 5√3 type notation. 26 doesn't have a perfect square to factor out.
5) you can complete the square on quadratics to make it look nicer. Its gives a prettier, more compact, and totally useless form of the equation.
I think Mahir wants what you call "mixed" notation.

Here's an example that Mahir can hopefully integrate within his program:
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Example program
#include <iostream>
#include <cmath>

///
/// (3, 3) --> 3 * sqrt(3)
/// (3, 1) --> 3
/// (1, 3) --> sqrt(3)
///
void print(int outside, int radicand)
{
    if (outside == 1 && radicand == 1)
        std::cout << 1;
    else
    {
        if (outside > 1)
            std::cout << outside;
        if (outside > 1 && radicand > 1)
            std::cout << " * ";
        if (radicand > 1)
            std::cout << "sqrt(" << radicand << ")"; // replace with the fancy symbol if you'd like
    }
    std::cout << std::endl;
}

int main()
{
    // assumes positive radicand (i.e. you've already checked for real/imaginry behavior)
    // assumes integer radicand (if the radicand isn't an integer, you're already
    //        starting off from a bad place beacuse FP math is inherently inexact)
    // If you wanted to be fancy, you could make this work with fractions.
    // Disclaimer: I don't know if this is the most efficient way to do this.

    int radicand = 72; // input your number here
    int outside = 1;

    int i = 2;
    while (i * i <= radicand)
    {
        if (radicand % (i*i) == 0)
        {
            radicand /= (i*i);
            outside  *= i;
            i = 2;
        }
        else
        {
            i++;
        }
    }
 
    print(outside, radicand);
}


Edit: Fixed some logic.
Last edited on
Topic archived. No new replies allowed.