This works by turning the strings inputted in a specific base into a ratio of four BigInts; two for the real part (numerator and denominator), and two for the imaginary. It then uses
https://github.com/brmbrmcar/ComplexFraction to perform the calculations, and the results are then turned back into a string with the provided base system. The end results are limited to fifty places after the '.' so that the information fits.
The conversion between strings and fractions uses some old code I used for a now deleted project, which is why it does not look particularly fitting for this page. The strings are converted into fractions by splitting the string into the integer part, the terminating fractional part and the recurring fractional part. The integer part is turned into a number by multiplying each character's position in the base string and the base length to the power of its distance from the '.'. The values of these characters are the added together. The terminating fractional part is processed in a similar way, but at the end it is divided by its base length to the power of its length. The recurring part is also calculated in a similar way, but it is divided by not only what the terminating decimal part was, but also its base length to the power of its length all subtracted by one. These are then added together to make a single fraction, and the same is done to the other strings provided. These can then be entered into the complex number library.
The fraction is then converted into a string by first finding the value of the integer part by dividing the numerator by the denominator and rounding towards zero. The remainder from dividing the integer part by the base length is calculated, and this position in the base string is added to the front of the output string. This remainder is then subtracted from the integer value and the integer value is divided by the base length. This is repeated until the integer value is zero. The integer value is subtracted from the total value of the fraction to find the fraction of the fractional parts. The factors of the base length are found, and the minimum number of these that can divide the fractional value represents the length of the terminating fractional part. The recurring part will be equal to a fraction with a denominator one less than a power of the base length. The power is equal to the length of the recurring part. The fractional part is then calculated using a process very similar to short division. After all the terminating characters are found, a '(' is placed, if there is a recurring part. Once all the recurring characters are found, a ')' is found and the string is created! A '-' is placed at the start if the fraction is negative. This is then concatenated with the other complex string to make the output.
Fractions are stored as followed: real numerator (BigInt), real denominator (BigInt), real negative? (Boolean), imaginary numerator (BigInt), imaginary denominator (BigInt), imaginary negative? (Boolean), along with all the functions that may be performed on them.
Adding is done by making the real and imaginary parts have the same denominators as their corresponding parts in the other object. This is done by multiplying both the numerator and the denominator by the opposite denominator. If a particular part's negativity is 'true', its numerator is multiplied by -one to make it negative. The numerators can then simply be added together to make a single object.
Subtracting is very similar to adding, except the numerators are subtracted instead of added.
When multiplying, if a part is negative, its numerator will be multiplied by -one. The real part is found by multiplying the real numerators and denominators together and subtracting from this the imaginary numerators and denominators muliplied together. The imaginary part is calculated by multiplying the real numerators and denominators by their opposite imaginary numerators and denominators and adding the results.
Dividing is performed by multiplying the first complex number by the reciprocal of the second. The reciprocal of the complex number is found by multiplying the real and imaginary denominators of its conjugate by the conjugate multiplied by the complex number.
Raising one complex number to the power of another is done by taking the natural logarithm of the base, multiplying this by the exponent and raising e to the power of all of this.
Raising a complex number to an integer power is done by multiplying the complex number by itself the exponent-one times. If the power is negative, the reciprocal of the result is returned.
The square root and cube root functions use Newton's method. The seed is determined based on whether the complex number is a positive real, a negative real or has an imaginary part.
The absolute value is found by squaring the real and imarginary fractions, adding them and then finding the square root of the result.
The argument is found by subtracting the real part from the absolute value, dividing this by the imaginary fraction, finding the inverse tangent of all this and multiplying by two.
The natural logarithm is found using the identity ln(x) = ln(r) + iy, where re^(iy) = x. y is merely the argument of the function, and r is the absolute value. The natural log of the absolute value is found using the series expansion for the inverse hyperbolic tangent. This is made more effecient by taking it's reciprocal and making the result negative wen r is below one and removing ln(two) repeatedly to get a faster convergence.
Raising e to the power of a complex number uses a power series. This is made more effecient by making the imaginary part as close to zero as possible, using the fact that it will remain equal when two*pi is subtracted or added to it, and subtracting two from the exponent and multiplying it by e^two.
Sine, cosine, tangent and their hyperbolic equivalents are estimated using their exponential forms.
Inverse sine, inverse cosine, their hyperbolic equivalents and inverse hyperbolic tangent are estimated using their logarithmic forms (rearranged from their exponential forms).
The inverse tangent is calculated mostly using its own series, however for some complex values it uses natural logarithms as they would not converge otherwise.