TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
quadratic_equations_complex_numbers.cpp
Go to the documentation of this file.
1
30
31
#include <array>
32
#include <cassert>
33
#include <cmath>
34
#include <complex>
35
#include <exception>
36
#include <iomanip>
37
#include <iostream>
38
43
namespace
math
{
44
53
std::array<std::complex<long double>, 2>
quadraticEquation
(
long
double
a,
54
long
double
b,
55
long
double
c) {
56
if
(a == 0) {
57
throw
std::invalid_argument(
"quadratic coefficient cannot be 0"
);
58
}
59
60
long
double
discriminant = b * b - 4 * a * c;
61
std::array<std::complex<long double>, 2> solutions{0, 0};
62
63
if
(discriminant == 0) {
64
solutions[0] = -b * 0.5 / a;
65
solutions[1] = -b * 0.5 / a;
66
return
solutions;
67
}
68
69
// Complex root (discriminant < 0)
70
// Note that the left term (-b / 2a) is always real. The imaginary part
71
// appears when b^2 - 4ac < 0, so sqrt(b^2 - 4ac) has no real roots. So,
72
// the imaginary component is i * (+/-)sqrt(abs(b^2 - 4ac)) / 2a.
73
if
(discriminant > 0) {
74
// Since discriminant > 0, there are only real roots. Therefore,
75
// imaginary component = 0.
76
solutions[0] = std::complex<long double>{
77
(-b - std::sqrt(discriminant)) * 0.5 / a, 0};
78
solutions[1] = std::complex<long double>{
79
(-b + std::sqrt(discriminant)) * 0.5 / a, 0};
80
return
solutions;
81
}
82
// Since b^2 - 4ac is < 0, for faster computation, -discriminant is
83
// enough to make it positive.
84
solutions[0] = std::complex<long double>{
85
-b * 0.5 / a, -std::sqrt(-discriminant) * 0.5 / a};
86
solutions[1] = std::complex<long double>{
87
-b * 0.5 / a, std::sqrt(-discriminant) * 0.5 / a};
88
89
return
solutions;
90
}
91
92
}
// namespace math
93
100
void
assertArray
(std::array<std::complex<long double>, 2> input,
101
std::array<std::complex<long double>, 2> expected,
102
size_t
precision = 10) {
103
long
double
exponent = std::pow(10, precision);
104
input[0].real(std::round(input[0].real() * exponent));
105
input[1].real(std::round(input[1].real() * exponent));
106
input[0].imag(std::round(input[0].imag() * exponent));
107
input[1].imag(std::round(input[1].imag() * exponent));
108
109
expected[0].real(std::round(expected[0].real() * exponent));
110
expected[1].real(std::round(expected[1].real() * exponent));
111
expected[0].imag(std::round(expected[0].imag() * exponent));
112
expected[1].imag(std::round(expected[1].imag() * exponent));
113
114
assert(input == expected);
115
}
116
122
static
void
test
() {
123
// Values are equal and real.
124
std::cout <<
"Input: \n"
125
"a=1 \n"
126
"b=-2 \n"
127
"c=1 \n"
128
"Expected output: \n"
129
"(1, 0), (1, 0)\n\n"
;
130
std::array<std::complex<long double>, 2> equalCase{
131
std::complex<long double>{1, 0}, std::complex<long double>{1, 0}};
132
assert(
math::quadraticEquation
(1, -2, 1) == equalCase);
133
134
// Values are equal and complex.
135
std::cout <<
"Input: \n"
136
"a=1 \n"
137
"b=4 \n"
138
"c=5 \n"
139
"Expected output: \n"
140
"(-2, -1), (-2, 1)\n\n"
;
141
std::array<std::complex<long double>, 2> complexCase{
142
std::complex<long double>{-2, -1}, std::complex<long double>{-2, 1}};
143
assert(
math::quadraticEquation
(1, 4, 5) == complexCase);
144
145
// Values are real.
146
std::cout <<
"Input: \n"
147
"a=1 \n"
148
"b=5 \n"
149
"c=1 \n"
150
"Expected output: \n"
151
"(-4.7912878475, 0), (-0.2087121525, 0)\n\n"
;
152
std::array<std::complex<long double>, 2> floatCase{
153
std::complex<long double>{-4.7912878475, 0},
154
std::complex<long double>{-0.2087121525, 0}};
155
assertArray
(
math::quadraticEquation
(1, 5, 1), floatCase);
156
157
// Values are complex.
158
std::cout <<
"Input: \n"
159
"a=1 \n"
160
"b=1 \n"
161
"c=1 \n"
162
"Expected output: \n"
163
"(-0.5, -0.8660254038), (-0.5, 0.8660254038)\n\n"
;
164
std::array<std::complex<long double>, 2> ifloatCase{
165
std::complex<long double>{-0.5, -0.8660254038},
166
std::complex<long double>{-0.5, 0.8660254038}};
167
assertArray
(
math::quadraticEquation
(1, 1, 1), ifloatCase);
168
169
std::cout <<
"Exception test: \n"
170
"Input: \n"
171
"a=0 \n"
172
"b=0 \n"
173
"c=0\n"
174
"Expected output: Exception thrown \n"
;
175
try
{
176
math::quadraticEquation
(0, 0, 0);
177
}
catch
(std::invalid_argument& e) {
178
std::cout <<
"Exception thrown successfully \n"
;
179
}
180
}
181
186
int
main
() {
187
test
();
// Run self-test implementation.
188
return
0;
189
}
test
void test()
Definition
caesar_cipher.cpp:100
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
math
for assert
math::quadraticEquation
std::array< std::complex< long double >, 2 > quadraticEquation(long double a, long double b, long double c)
Quadratic equation calculator.
Definition
quadratic_equations_complex_numbers.cpp:53
assertArray
void assertArray(std::array< std::complex< long double >, 2 > input, std::array< std::complex< long double >, 2 > expected, size_t precision=10)
Asserts an array of complex numbers.
Definition
quadratic_equations_complex_numbers.cpp:100
math
quadratic_equations_complex_numbers.cpp
Generated by
1.18.0