amath  1.8.5
Simple command line calculator
cplex.cpp
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  */
29 
30 #include "mathr.h"
31 #include "mathi.h"
32 #include "real.h"
33 #include "cplex.h"
34 #include "nnumb.h"
35 
37 {
38  z = cpack(0.0, 0.0);
39 }
40 
42 {
43  this->z = z;
44 }
45 
46 ComplexNumber::ComplexNumber(double real, double imag) : Number(nsyscomplex)
47 {
48  z = cpack(real, imag);
49 }
50 
52 {
53 }
54 
56 {
57  return new ComplexNumber(z);
58 }
59 
61 {
62  return static_cast<int>(creal(z));
63 }
64 
66 {
67  return creal(z);
68 }
69 
70 double ComplexNumber::GetImagValue() const
71 {
72  return cimag(z);
73 }
74 
76 {
77  return z;
78 }
79 
81 {
82  return (creal(z) == 0.0);
83 }
84 
86 {
87  if ((creal(z) < 0.0) || (creal(z) == 0.0 && cimag(z) < 0.0))
88  {
89  return -1;
90  }
91  else if (creal(z) != 0.0 && cimag(z) != 0.0)
92  {
93  return 2;
94  }
95  else
96  {
97  return 0;
98  }
99 }
100 
102 {
103  return (creal(z) != 0.0 && cimag(z) != 0.0) ? 2 : 0;
104 }
105 
107 {
108  FloatUnion64 d, e;
111  return d.IsNegative() && e.IsNegative();
112 }
113 
115 {
116  FloatUnion64 d, e;
119  return d.IsZero() && e.IsZero();
120 }
121 
122 /**
123  * @brief Returns true if number is NaN
124  */
126 {
127  FloatUnion64 d, e;
130  return d.IsNaN() || e.IsNaN();
131 }
132 
133 /**
134  * @brief Returns true if number is infinite
135  */
137 {
138  double a = creal(z);
139  double b = cimag(z);
140 
141  // Handle subnormal values
142  bool subInf =
143  (a > 0 && a <= 1e-308) || (a < 0 && a >= -1e-308) ||
144  (b > 0 && b <= 1e-308) || (b < 0 && b >= -1e-308);
145 
146  if (subInf)
147  {
148  return true;
149  }
150 
151  FloatUnion64 d, e;
152  d.floatingPoint = a;
153  e.floatingPoint = b;
154  return d.IsInf() || e.IsInf() ||
157 }
158 
160 {
161  return false;
162 }
163 
165 {
166  complex w = cpack(-creal(z), -cimag(z));
167  return new ComplexNumber(w);
168 }
169 
171 {
172  if (other->IsNaN())
173  return new NonNumber(nnnan);
174 
175  if (other->system == nsyscomplex)
176  {
177  ComplexNumber *w = static_cast<ComplexNumber *>(other);
178  return new ComplexNumber(cadd(z, w->z));
179  }
180 
181  if (other->system == nsysreal)
182  {
183  RealNumber *a = static_cast<RealNumber *>(other);
184  return new ComplexNumber(cadd(z, cpack(a->x, 0.0)));
185  }
186 
187  return new ComplexNumber();
188 }
189 
191 {
192  if (other->IsNaN())
193  return new NonNumber(nnnan);
194 
195  if (other->system == nsyscomplex)
196  {
197  ComplexNumber *w = static_cast<ComplexNumber *>(other);
198  return new ComplexNumber(csub(z, w->z));
199  }
200 
201  if (other->system == nsysreal)
202  {
203  RealNumber *a = static_cast<RealNumber *>(other);
204  return new ComplexNumber(csub(z, cpack(a->x, 0.0)));
205  }
206 
207  return new ComplexNumber();
208 }
209 
211 {
212  if (other->IsNaN())
213  return new NonNumber(nnnan);
214 
215  if (other->system == nsyscomplex)
216  {
217  ComplexNumber *w = static_cast<ComplexNumber *>(other);
218  return new ComplexNumber(cmul(z, w->z));
219  }
220 
221  if (other->system == nsysreal)
222  {
223  RealNumber *a = static_cast<RealNumber *>(other);
224  return new ComplexNumber(cmul(z, cpack(a->x, 0.0)));
225  }
226 
227  return new ComplexNumber();
228 }
229 
231 {
232  if (other->IsZero() || other->IsNaN())
233  return new NonNumber(nnnan);
234 
235  if (other->system == nsyscomplex)
236  {
237  ComplexNumber *w = static_cast<ComplexNumber *>(other);
238  return new ComplexNumber(cdiv(z, w->z));
239  }
240 
241  if (other->system == nsysreal)
242  {
243  RealNumber *a = static_cast<RealNumber *>(other);
244  return new ComplexNumber(cdiv(z, cpack(a->x, 0.0)));
245  }
246 
247  return new ComplexNumber();
248 }
249 
251 {
252  if (exponent->IsNaN())
253  return new NonNumber(nnnan);
254 
255  if (exponent->system == nsyscomplex)
256  {
257  ComplexNumber *w = static_cast<ComplexNumber *>(exponent);
258  return new ComplexNumber(cpow(z, w->z));
259  }
260 
261  if (exponent->system == nsysreal)
262  {
263  RealNumber *a = static_cast<RealNumber *>(exponent);
264  return new ComplexNumber(cpow(z, cpack(a->x, 0.0)));
265  }
266 
267  return new ComplexNumber();
268 }
269 
271 {
272  return new NonNumber(nnnimp);
273 }
274 
276 {
277  return new RealNumber(csgn(z));
278 }
279 
281 {
282  return new RealNumber(cabs(z));
283 }
284 
286 {
287  return new ComplexNumber(ctrunc(z));
288 }
289 
291 {
292  return new ComplexNumber(cround(z));
293 }
294 
296 {
297  return new ComplexNumber(cfloor(z));
298 }
299 
301 {
302  return new ComplexNumber(cceil(z));
303 }
304 
306 {
307  return new ComplexNumber(csqrt(z));
308 }
309 
311 {
312  return new ComplexNumber(creci(z));
313 }
314 
316 {
317  return new ComplexNumber(ccbrt(z));
318 }
319 
321 {
322  if (creal(z) == 0.0 && cimag(z) == 0.0)
323  return new NonNumber(nnnan);
324 
325  return new ComplexNumber(clog(z));
326 }
327 
329 {
330  if (creal(z) == 0.0 && cimag(z) == 0.0)
331  return new NonNumber(nnnan);
332 
333  return new ComplexNumber(clogb(z));
334 }
335 
337 {
338  if (creal(z) == 0.0 && cimag(z) == 0.0)
339  return new NonNumber(nnnan);
340 
341  return new ComplexNumber(clog10(z));
342 }
343 
345 {
346  return new ComplexNumber(csin(z));
347 }
348 
350 {
351  return new ComplexNumber(ccos(z));
352 }
353 
355 {
356  return new ComplexNumber(ctan(z));
357 }
358 
360 {
361  return new ComplexNumber(csec(z));
362 }
363 
365 {
366  return new ComplexNumber(ccsc(z));
367 }
368 
370 {
371  return new ComplexNumber(ccot(z));
372 }
373 
375 {
376  return new NonNumber(nnnimp);
377 }
378 
380 {
381  return new NonNumber(nnnimp);
382 }
383 
385 {
386  return new NonNumber(nnnimp);
387 }
388 
390 {
391  return new ComplexNumber(casin(z));
392 }
393 
395 {
396  return new ComplexNumber(cacos(z));
397 }
398 
400 {
401  return new ComplexNumber(catan(z));
402 }
403 
405 {
406  return new ComplexNumber(casec(z));
407 }
408 
410 {
411  return new ComplexNumber(cacsc(z));
412 }
413 
415 {
416  return new ComplexNumber(cacot(z));
417 }
418 
420 {
421  return new NonNumber(nnnimp);
422 }
423 
425 {
426  return new NonNumber(nnnimp);
427 }
428 
430 {
431  return new NonNumber(nnnimp);
432 }
433 
435 {
436  return new ComplexNumber(csinh(z));
437 }
438 
440 {
441  return new ComplexNumber(ccosh(z));
442 }
443 
445 {
446  return new ComplexNumber(ctanh(z));
447 }
448 
450 {
451  return new ComplexNumber(csech(z));
452 }
453 
455 {
456  return new ComplexNumber(ccsch(z));
457 }
458 
460 {
461  return new ComplexNumber(ccoth(z));
462 }
463 
465 {
466  return new ComplexNumber(casinh(z));
467 }
468 
470 {
471  return new ComplexNumber(cacosh(z));
472 }
473 
475 {
476  return new ComplexNumber(catanh(z));
477 }
478 
480 {
481  return new ComplexNumber(casech(z));
482 }
483 
485 {
486  return new ComplexNumber(cacsch(z));
487 }
488 
490 {
491  return new ComplexNumber(cacoth(z));
492 }
493 
495 {
496  return new NonNumber(nnnimp);
497 }
498 
500 {
501  return new NonNumber(nnnimp);
502 }
503 
505 {
506  return new NonNumber(nnnimp);
507 }
508 
510 {
511  return new NonNumber(nnnimp);
512 }
513 
515 {
516  return new NonNumber(nnnimp);
517 }
518 
520 {
521  return new NonNumber(nnnimp);
522 }
523 
525 {
526  return new NonNumber(nnnimp);
527 }
528 
530 {
531  return new NonNumber(nnnimp);
532 }
533 
535 {
536  return new NonNumber(nnnimp);
537 }
538 
540 {
541  return new NonNumber(nnnimp);
542 }
543 
545 {
546  return new NonNumber(nnnimp);
547 }
548 
550 {
551  return new NonNumber(nnnimp);
552 }
553 
555 {
556  return new NonNumber(nnnimp);
557 }
558 
560 {
561  return new NonNumber(nnnimp);
562 }
563 
565 {
566  return new NonNumber(nnnimp);
567 }
568 
570 {
571  return new NonNumber(nnnimp);
572 }
Number * ArcVerSine()
Definition: cplex.cpp:534
Number * Floor()
Definition: cplex.cpp:295
complex csech(complex z)
Hyperbolic secant of a complex number.
Definition: csech.c:48
Number * ArcExCosecant()
Definition: cplex.cpp:429
ComplexNumber(complex z)
Definition: cplex.cpp:41
Number * ArcTangent()
Definition: cplex.cpp:399
complex ctanh(complex z)
Hyperbolic tangent of a complex number.
Definition: ctanh.c:53
Represent a number which does not exists.
Definition: nnumb.h:51
Number * HypArcCotangent()
Definition: cplex.cpp:489
bool IsNaN() const
Definition: numb.h:48
Number * HypCosecant()
Definition: cplex.cpp:454
complex ctan(complex z)
Tangent of a complex number.
Definition: ctan.c:55
int GetPrecedence()
Definition: cplex.cpp:85
Number * HaVerCosine()
Definition: cplex.cpp:519
Number * HypCotangent()
Definition: cplex.cpp:459
complex clog(complex z)
Natural logarithm of a complex number.
Definition: clog.c:42
Number * Cotangent()
Definition: cplex.cpp:369
Number(NumberSystem system)
Definition: numb.h:69
Definition: nnumb.h:42
complex csub(complex a, complex z)
Subtraction of two complex numbers.
Definition: prim.c:130
int GetIntegerValue()
Definition: cplex.cpp:60
Number * SquareRoot()
Definition: cplex.cpp:305
Number * HaCoVerSine()
Definition: cplex.cpp:524
complex casec(complex z)
Inverse secant expressed using complex logarithms:
Definition: casec.c:42
complex cpow(complex x, complex z)
Complex number raised to a power.
Definition: cpow.c:42
complex cround(complex z)
Division of two complex numbers.
Definition: prim.c:110
Number * ArcCoVerSine()
Definition: cplex.cpp:544
NumberSystem system
Definition: numb.h:171
Number * Log()
Definition: cplex.cpp:320
NonNumber(NonNumberType type)
Definition: nnumb.cpp:33
Number * CoVerSine()
Definition: cplex.cpp:504
virtual bool IsZero()=0
double creal(complex z)
Real part of complex number.
Definition: prim.c:38
complex cadd(complex a, complex z)
Addition of two complex numbers.
Definition: prim.c:120
Number * HypArcSecant()
Definition: cplex.cpp:479
complex casinh(complex z)
Inverse hyperbolic sine of complex number.
Definition: casinh.c:47
Number * Secant()
Definition: cplex.cpp:359
Number * VerSine()
Definition: cplex.cpp:494
Number * Reciprocal()
Definition: cplex.cpp:310
complex z
Definition: cplex.h:141
Number * Unary()
Definition: cplex.cpp:164
complex cdiv(complex a, complex z)
Division of two complex numbers.
Definition: prim.c:159
int GetDefaultPrecedence()
Definition: cplex.cpp:101
Number * ArcExSecant()
Definition: cplex.cpp:424
Number * HypTangent()
Definition: cplex.cpp:444
Definition: numb.h:66
Number * Clone()
Definition: cplex.cpp:55
Number * Tangent()
Definition: cplex.cpp:354
complex clogb(complex z)
Base 2 logarithmic value of complex number.
Definition: clogb.c:41
complex ctrunc(complex z)
Truncated value of complex number.
Definition: prim.c:80
bool IsInf() const
Definition: numb.h:47
bool IsMaxNegative() const
Definition: numb.h:50
complex clog10(complex z)
Base 10 logarithmic value of complex number.
Definition: clog10.c:41
bool IsNegative() const
Definition: numb.h:45
Number * HypSecant()
Definition: cplex.cpp:449
complex csqrt(complex z)
Square root of complex number.
Definition: csqrt.c:42
Number * HypArcTangent()
Definition: cplex.cpp:474
double floatingPoint
Definition: numb.h:53
Number * ArcCosine()
Definition: cplex.cpp:394
complex catanh(complex z)
Inverse hyperbolic tangent of complex number.
Definition: catanh.c:42
complex csinh(complex z)
Hyperbolic sine of a complex number.
Definition: csinh.c:50
complex cacsch(complex z)
Inverse hyperbolic cosecant of complex number.
Definition: cacsch.c:42
Number * HypArcCosecant()
Definition: cplex.cpp:484
virtual bool IsNaN()=0
double GetRealValue()
Definition: cplex.cpp:65
double cabs(complex z)
Absolute value of complex number.
Definition: prim.c:54
bool IsNegative()
Definition: cplex.cpp:106
Number * Div(Number *other)
Definition: cplex.cpp:230
complex ccosh(complex z)
Hyperbolic cosine of a complex number.
Definition: ccosh.c:48
Number * Trunc()
Definition: cplex.cpp:285
Number * ArcHaCoVerCosine()
Definition: cplex.cpp:569
Number * Add(Number *other)
Definition: cplex.cpp:170
Represent a real number with 15 significant digits.
Definition: real.h:45
complex cfloor(complex z)
Floor value of complex number.
Definition: prim.c:90
complex cpack(double x, double y)
Pack two real numbers into a complex number.
Definition: prim.c:68
Number * ArcHaVerCosine()
Definition: cplex.cpp:559
Number * ArcVerCosine()
Definition: cplex.cpp:539
complex cceil(complex z)
Ceiling value of complex number.
Definition: prim.c:100
bool IsZero()
Definition: cplex.cpp:114
complex ccsch(complex z)
Hyperbolic secant of a complex number.
Definition: ccsch.c:48
Number * HypSine()
Definition: cplex.cpp:434
complex ccsc(complex z)
Cosecant of a complex number.
Definition: ccsc.c:48
ComplexNumber()
Definition: cplex.cpp:36
double cimag(complex z)
Imaginary part of complex number.
Definition: prim.c:46
Number * HypCosine()
Definition: cplex.cpp:439
complex ccbrt(complex z)
Cube root of complex number.
Definition: ccbrt.c:41
Number * ArcChord()
Definition: cplex.cpp:419
complex cmul(complex a, complex z)
Multiplication of two complex numbers.
Definition: prim.c:140
complex csec(complex z)
Secant of a complex number.
Definition: csec.c:48
double x
Definition: real.h:143
Number * HaCoVerCosine()
Definition: cplex.cpp:529
Number * HaVerSine()
Definition: cplex.cpp:514
Number * Log10()
Definition: cplex.cpp:336
Definition: nnumb.h:45
Number * Cosecant()
Definition: cplex.cpp:364
Number * Absolute()
Definition: cplex.cpp:280
Number * ArcHaCoVerSine()
Definition: cplex.cpp:564
complex cacot(complex z)
Inverse cotangent of complex number.
Definition: cacot.c:42
Represent a complex number with 2 components of 15 significant digits.
Definition: cplex.h:46
double csgn(complex z)
Complex signum.
Definition: csgn.c:38
bool IsNaN()
Returns true if number is NaN.
Definition: cplex.cpp:125
Number * Sine()
Definition: cplex.cpp:344
bool IsMaxPositive() const
Definition: numb.h:49
bool IsZero() const
Definition: numb.h:46
Number * VerCosine()
Definition: cplex.cpp:499
complex GetComplexValue() const
Definition: cplex.cpp:75
Number * ExSecant()
Definition: cplex.cpp:379
Number * Sub(Number *other)
Definition: cplex.cpp:190
Number * ArcSine()
Definition: cplex.cpp:389
complex ccoth(complex z)
Hyperbolic cotangent of a complex number.
Definition: ccoth.c:50
Number * Signum()
Definition: cplex.cpp:275
Number * HypArcCosine()
Definition: cplex.cpp:469
complex casech(complex z)
Inverse hyperbolic secant of complex numbers.
Definition: casech.c:42
RealNumber(double x)
Definition: real.cpp:42
Number * Round()
Definition: cplex.cpp:290
ComplexNumber(double real, double imag)
Definition: cplex.cpp:46
complex ccot(complex z)
Cotangent of a complex number.
Definition: ccot.c:48
Number * ExCosecant()
Definition: cplex.cpp:384
Number * Ceiling()
Definition: cplex.cpp:300
~ComplexNumber()
Definition: cplex.cpp:51
complex catan(complex z)
Inverse tangent of complex number.
Definition: catan.c:42
Number * HypArcSine()
Definition: cplex.cpp:464
complex cacsc(complex z)
Inverse cosecant of complex number.
Definition: cacsc.c:42
Number * Chord()
Definition: cplex.cpp:374
complex casin(complex z)
Inverse sine of complex number.
Definition: casin.c:42
complex cacoth(complex z)
Inverse hyperbolic cotangent of complex number.
Definition: cacoth.c:42
Number * ArcCosecant()
Definition: cplex.cpp:409
Number * CubeRoot()
Definition: cplex.cpp:315
Number * ArcCoVerCosine()
Definition: cplex.cpp:549
Number * ArcSecant()
Definition: cplex.cpp:404
double GetImagValue() const
Definition: cplex.cpp:70
Number * ArcHaVerSine()
Definition: cplex.cpp:554
Number * Log2()
Definition: cplex.cpp:328
bool PureComplexValue()
Definition: cplex.cpp:80
complex cacosh(complex z)
Inverse hyperbolic cosine of complex number.
Definition: cacosh.c:42
bool IsNotImplemented()
Definition: cplex.cpp:159
Number * CoVerCosine()
Definition: cplex.cpp:509
Number * ArcCotangent()
Definition: cplex.cpp:414
Number * Cosine()
Definition: cplex.cpp:349
complex ccos(complex z)
Cosine of complex number.
Definition: ccos.c:45
complex creci(complex z)
Reciprocal value of complex number.
Definition: prim.c:181
complex cacos(complex z)
Inverse cosine of complex number.
Definition: cacos.c:42
bool IsInfinite()
Returns true if number is infinite.
Definition: cplex.cpp:136
Number * Mul(Number *other)
Definition: cplex.cpp:210
Number * Raise(Number *exponent)
Definition: cplex.cpp:250
complex csin(complex z)
Sine of a complex number.
Definition: csin.c:50
Number * Factorial()
Definition: cplex.cpp:270
Definition: numb.h:61