Search code examples
javascripttrigonometrycomplex-numbers

Javascript - Error when calculating sine of complex numbers with a high magnitude


I am making a sine calculator that will be able to evaluate the sine of complex numbers by using polar coordinates and calculating part of the infinite series that defines the sine function. The calculator seems to work fine if the magnitude of the inputted complex number is small. However, when the magnitude of the inputted complex number becomes large (over 40) the calculator stops working, as the system seems to be outputting the real and imaginary portions of the final result as NaN. Please may you help me make my calculator work for all complex inputs? Any help would be greatly appreciated. Here is my HTML and JS code:

var arr=[];
var result=[0,0];
function calc(){
var input=document.querySelector("input").value;
try{if(input.split("+").length == 1){
arr[0]=Number(input.split("-")[0])
arr[1]=-1*Number(input.split("-")[1].split("i").join(""))
if(input.split("-")[1].split("i").join("") === ""){
arr[1] = -1;
}
}else{
arr[0]=Number(input.split("+")[0])
arr[1]=Number(input.split("+")[1].split("i").join(""))
if(input.split("+")[1].split("i").join("") === ""){
arr[1] = 1;
}
}
}catch(e){if(input.split("i").length == 1){arr[0] = Number(input);arr[1]=0}}
for(var i=0;i<100;i++){
result[0] += ((-1)**i)*calcPower(2*i+1)[0]/factorialize(2*i+1)
result[1] += ((-1)**i)*calcPower(2*i+1)[1]/factorialize(2*i+1)
}
document.querySelector("div").innerText=result[0]+sign(result[1])+Math.abs(result[1])+"i";
result[0]=0;
result[1]=0;
}
function calcPower(pow){
var r=(arr[0]**2+arr[1]**2)**0.5;
if(Math.sign(arr[0])+Math.sign(arr[1]) == -2){
r *= -1}
r **= pow;
var real=Math.cos(Math.atan(arr[1]/arr[0])*pow)*r;
var imag=Math.sin(Math.atan(arr[1]/arr[0])*pow)*r;
return [real,imag];
}
function factorialize(factorial){
var result=1;
for(var i=1;i<=factorial;i++){result *= i};return result}
function sign(num){if(Math.sign(num) == -1){return "-"}else{return "+"}}
<input></input>
<button onclick=calc()>Take the sine of the complex number</button>
<br>
<div id=output style=font-size:20px></div>


Solution

  • I ran your code and the problem occurred on this line:

    r **= pow;
    

    When I used "54" as an input, the last iteration it could handle was r=54 & pow = 177, which produced 4.3022484685528774e+306. In the next iteration pow became 179, which produced Infinity, because it had exceeded the limits of 64 bit floats.

    One way to deal with this issue is to use BigInt for the portions of your code that don't require the data after the decimal point. I made a fiddle here where you can see that BigInt can handle 54**179. https://jsfiddle.net/afyk6rbu/

    const big = BigInt(54)**BigInt(179)
    
    console.log(big.toString())
    console.log(Number(big))
    

    The toString shows that it has successfully calculated the values, but Number(big) shows that the number is too large to fit in a normal number. It must be brought back into the range of a 64 bit float before it can be used for trig.