MHB Computing the value of sine function accurately

AI Thread Summary
The discussion centers on accurately computing the sine of a complex expression, \( a = \sin(2017 \sqrt[5]{2}) \), using only basic arithmetic operations without advanced numerical libraries. Participants suggest using the Newton-Raphson method to find the fifth root of 2 and employing series expansions for calculating trigonometric functions. The approach emphasizes maintaining high precision, aiming for at least 30-digit accuracy in intermediate calculations. A custom library for n-digit arithmetic is also discussed to facilitate the required computations. The overall goal is to derive the sine value with the necessary precision while adhering to the specified operational constraints.
Theia
Messages
121
Reaction score
1
Hi all
Simple question: How I can compute the value of \(a = \sin \left( 2017 \sqrt[5]{2} \right) \) under following assumptions:
  • No use of advanced numerical libraries is allowed.
  • Only accepted operations are: comparisons, absolute value, addition, subtraction, multiplication and division.
  • More advanced operations must be returned to the use of allowed operations.
  • End result is needed by 25 digit accuracy.
Ps. I know, \( a \approx -1 \), so equivalent way is to find the number \(b = 1 + a. \) But what is the easiest way to do that? :unsure:

Thank you!
 
Technology news on Phys.org
How about:
  1. Evaluate $\sqrt[5] 2$ by Newton Raphson with $f(x)=x^5-2$ and $x_{k+1}=x_k-\frac{f(x_k)}{f'(x_k)},\,x_0=2$.
  2. Evaluate $\tau=2\pi$ by one of its many algorithms. For instance $\tau = 8\tan^{-1}(1)=8\Big(1-\frac 13+\frac 15-\ldots\Big)$.
  3. Evaluate $x\overset{def}=\Big(2017\sqrt[5] 2 \bmod{\tau}\Big)-\frac 34\tau$.
  4. Evaluate $a=\sin\Big(x+\frac 34\tau\Big)=-\cos x=-\Big(1-\frac{x^2}{2!}+\frac{x^4}{4!}-\ldots\Big)$.
Intermediate results will need more than 25 digit accuracy.
A ballpark figure of 30 digit accuracy should suffice in this case.
 
Last edited:
Interesting! At least worth to try and see how it works! :giggle: Thank you!
 
My approach was:

I typed a very robust library to handle n-digit arithmetic. And then followed the scheme Klaas van Aarsen wrote.

Python:
# -*- coding: utf-8 -*-

#procedures for N-digit computation

#number of decimals
N = 30

def tofloat(string):
  #to convert number from string to N-float
  minus = string.find('-')
  if(minus > -1): #number is negative
    minus = -1
    #remove it from the string
    string = string.replace('-', '', 1)
  else:
    minus = 1
  dot = string.find('.')
  if(dot == -1): #if decimal point does not exist
    #return integer part
    ip = int(string)
    dp = 0
    number = [ip, dp, minus]
    return number
  #if decimal point exists
  ip = int(string[:dot]) #integer part
  dps = string[dot+1:] #decimal part as string
  ldps = len(dps) #length of decimal part
  if(ldps == N): #no extra digits
    dp = int(dps)
  elif(ldps > N): #extra digits
    dp = int(dps[:N]) #first N digits
    e = int(dps[N]) #next digit
    if(e > 4):
      dp += 1
    if(dp > ONE1):
      dp -= ONE
      ip += 1
  else: #too few digits
    a = N - ldps
    zeros = '0' *a
    dp = int(dps + zeros)
  number = [ip, dp, minus]
  return number
    
def show(number,out=1):
  #routines to print N-digit number
  ip = number[0]
  dp = number[1]
  minus = number[2]
  string = ''
  if(minus == -1):
    string = '-'
  string = string + str(ip)
  if(dp > 0):
    #how many digits in dp?
    dps = str(dp)
    a = N - len(dps) # zeros missing
    if(a > 0):
      zeros = '0' *a
    else:
      zeros = ''
    string = string + '.' + zeros + dps
  if(out == 1):
    print(string)
    return
  return string

def sum(a,b):
  #summation of numbers a and b
  na = a[0]*ONE + a[1]
  if(a[2] < 0):
    na = -na
  nb = b[0]*ONE + b[1]
  if(b[2] < 0):
    nb = -nb
  n = na + nb
  sig = 1
  #analyze the result
  if(n < 0):
    sig = -1
    n = -n
  number = [n // ONE,n % ONE,sig]
  return number

def subs(a,b):
  #substraction a - b
  number = sum(a,[b[0],b[1],-b[2]])
  return number

def prod(a,b):
  #product a*b
  #determine the sign of the result
  sig = a[2]*b[2]
  ip = a[0]*b[0]
  dp1 = a[0]*b[1]
  dp2 = a[1]*b[0]
  dp3 = a[1]*b[1]
  dp31 = dp3 // ONE
  #need to find the first dropped digit
  f = dp3 - ONE*dp31
  #one1d = ONE // 10
  f = f // ONE1D
  if(f > 4):
    dp31 += 1
  dp = dp1 + dp2 + dp31
  if(dp > ONE1):
    k = dp // ONE
    dp = dp % ONE
    ip += k
  number = [ip, dp, sig]
  return number

def div(a,b):
  #division a/b
  #sign of the result
  sig = a[2]*b[2]
  na = a[0]*ONE + a[1]
  na *= NSIFT1
  nb = b[0]*ONE + b[1]
  n = na // nb
  #last digit is for rounding
  r = n % 10
  n -= r
  n = n // 10
  #build number
  ip = n // ONE
  dp = n % ONE
  if(r > 4):
    dp += 1
    if(dp > ONE1):
      dp -= ONE
      ip += 1
  number = [ip,dp,sig]
  return number

NZEROS = '0' *N
NSIFT1 = int('1' + NZEROS + '0')
ONE = int('1' + NZEROS)
ONE1 = ONE - 1
ONE1D = ONE // 10

Python:
# -*- coding: utf-8 -*-

import ndigit as nd

#compute the value of a = sin(2017*(2)^(1/5))

def newite(x):
  #computes 5th root of x
  o = [1,0,1]
  r = nd.prod(x,nd.tofloat('0.3'))
  p4 = nd.tofloat('4')
  while((o[0] > 0) or ((o[0] == 0) and (o[1] > 20))):
    r2 = nd.prod(r,r)
    r4 = nd.prod(r2,r2)
    r5 = nd.prod(r,r4)
    o = nd.subs(r5,x)
    n = nd.prod(p4,r4)
    d = nd.div(o,n)
    r = nd.subs(r,d)
  return r

def macatan(x,err = 20):
  #computes atan(x) with error less than err/N units
  x2 = nd.prod(x,x)
  term = [5,0,1]
  su = x
  n = [1,0,1]
  sig = -1
  while((term[0] > 0) or ((term[0] == 0) and (term[1] > err))):
    x = nd.prod(x,x2)
    n = nd.sum(n,[2,0,1])
    term = nd.div(x,n)
    if(sig < 0):
      su = nd.subs(su,term)
      sig = 1
    else:
      su = nd.sum(su,term)
      sig = -1
  return su

#compute 2^(1/5) by Newton iteration
fth2 = newite(nd.tofloat('2'))

#compute pi using Machin's serie:
#pi = 4*(4*atan(1/5) - atan(1/239))
#   = 16*atan(1/5) - 4*atan(1/239)

x1 = nd.tofloat('0.2')
x2 = [239,0,1]
x2 = nd.div([1,0,1],x2) # 1/239

pi1 = macatan(x1,1)
pi1 = nd.prod(pi1,[16,0,1])
pi2 = macatan(x2)
pi2 = nd.prod(pi2,[4,0,1])

pi = nd.subs(pi1,pi2) # pi
pi2 = nd.sum(pi,pi) # 2*pi

#compute the number 2017*2^(1/5)...
x = nd.prod([2017,0,1],fth2)
#and remove 2pi-multiples
n2pi = nd.div(x,pi2)
xremove = nd.prod(pi2,[n2pi[0],0,1])
x = nd.subs(x,xremove)
#now x ~ 3pi/2. Difference is
pi32 = nd.sum(pi,pi2) # 3*pi
pi32 = nd.prod(pi32,nd.tofloat('0.5')) # 3*pi/2
x = nd.subs(x,pi32)

#compute the a = -cos(x) = -1 + x^2/2 - ...
#difference from -1

x2 = nd.prod(x,x)
x = [1,0,1]
sig = 1
v = 0
nim = [1,0,1]
term = [0,45677,1]
su = [0,0,1]
while(term[1] > 20):
  x = nd.prod(x,x2)
  v += 1
  nim = nd.prod(nim,[v,0,1])
  v += 1
  nim = nd.prod(nim,[v,0,1])
  term = nd.div(x,nim)
  if(sig > 0):
    su = nd.sum(su,term)
    sig = -1
  else:
    su = nd.subs(su,term)
    sig = 1

print('difference from -1:', nd.show(su,0))
a = nd.sum([1,0,-1],su)
print('value:', nd.show(a,0))

#correct value:
#-0.999999999999999978567771261060983
 
Thread 'Is this public key encryption?'
I've tried to intuit public key encryption but never quite managed. But this seems to wrap it up in a bow. This seems to be a very elegant way of transmitting a message publicly that only the sender and receiver can decipher. Is this how PKE works? No, it cant be. In the above case, the requester knows the target's "secret" key - because they have his ID, and therefore knows his birthdate.
I tried a web search "the loss of programming ", and found an article saying that all aspects of writing, developing, and testing software programs will one day all be handled through artificial intelligence. One must wonder then, who is responsible. WHO is responsible for any problems, bugs, deficiencies, or whatever malfunctions which the programs make their users endure? Things may work wrong however the "wrong" happens. AI needs to fix the problems for the users. Any way to...
Back
Top