Created
May 17, 2019 10:39
-
-
Save nagayev/8cdafcd7239880f18bf1cca7aa618c1d to your computer and use it in GitHub Desktop.
tan.js using golang sources
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2011 The Go Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style | |
// license that can be found in the LICENSE file. | |
/* | |
Floating-point tangent. | |
*/ | |
// The original C code, the long comment, and the constants | |
// below were from http://netlib.sandia.gov/cephes/cmath/sin.c, | |
// available from http://www.netlib.org/cephes/cmath.tgz. | |
// The go code is a simplified version of the original C. | |
// | |
// tan.c | |
// | |
// Circular tangent | |
// | |
// SYNOPSIS: | |
// | |
// double x, y, tan(); | |
// y = tan( x ); | |
// | |
// DESCRIPTION: | |
// | |
// Returns the circular tangent of the radian argument x. | |
// | |
// Range reduction is modulo pi/4. A rational function | |
// x + x**3 P(x**2)/Q(x**2) | |
// is employed in the basic interval [0, pi/4]. | |
// | |
// ACCURACY: | |
// Relative error: | |
// arithmetic domain # trials peak rms | |
// DEC +-1.07e9 44000 4.1e-17 1.0e-17 | |
// IEEE +-1.07e9 30000 2.9e-16 8.1e-17 | |
// | |
// Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss | |
// is not gradual, but jumps suddenly to about 1 part in 10e7. Results may | |
// be meaningless for x > 2**49 = 5.6e14. | |
// [Accuracy loss statement from sin.go comments.] | |
// | |
// Cephes Math Library Release 2.8: June, 2000 | |
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier | |
// | |
// The readme file at http://netlib.sandia.gov/cephes/ says: | |
// Some software in this archive may be from the book _Methods and | |
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster | |
// International, 1989) or from the Cephes Mathematical Library, a | |
// commercial product. In either event, it is copyrighted by the author. | |
// What you see here may be used freely but it comes with no support or | |
// guarantee. | |
// | |
// The two known misprints in the book are repaired here in the | |
// source listings for the gamma function and the incomplete beta | |
// integral. | |
// | |
// Stephen L. Moshier | |
// [email protected] | |
// tan coefficients | |
var _tanP = [ | |
-1.30936939181383777646e4, // 0xc0c992d8d24f3f38 | |
1.15351664838587416140e6, // 0x413199eca5fc9ddd | |
-1.79565251976484877988e7, // 0xc1711fead3299176 | |
] | |
var _tanQ = [ | |
1.00000000000000000000e0, | |
1.36812963470692954678e4, //0x40cab8a5eeb36572 | |
-1.32089234440210967447e6, //0xc13427bc582abc96 | |
2.50083801823357915839e7, //0x4177d98fc2ead8ef | |
-5.38695755929454629881e7, //0xc189afe03cbe5a31 | |
] | |
// Tan returns the tangent of the radian argument x. | |
// | |
// Special cases are: | |
// Tan(±0) = ±0 | |
// Tan(±Inf) = NaN | |
// Tan(NaN) = NaN | |
function tan(x){ | |
const | |
PI4A = 7.85398125648498535156e-1 // 0x3fe921fb40000000, Pi/4 split into three parts | |
PI4B = 3.77489470793079817668e-8 // 0x3e64442d00000000, | |
PI4C = 2.69515142907905952645e-15 // 0x3ce8469898cc5170, | |
// special cases | |
if(x == 0 || Number.isNaN(x)) | |
return x // return ±0 || NaN() | |
if(Number.isFinite(x)) | |
return NaN | |
// make argument positive but save the sign | |
var sign = false | |
if(x < 0){ | |
x = -x | |
sign = true | |
} | |
var j; | |
var y, z; | |
if(x >= reduceThreshold){ | |
j, z = trigReduce(x) | |
} else { | |
j = parseInt(x * (4 / Pi)) // integer part of x/(Pi/4), as integer for tests on the phase angle | |
y = parseFloat(j) // integer part of x/(Pi/4), as float | |
/* map zeros and singularities to origin */ | |
if(j&1 == 1){ | |
j++ | |
y++ | |
} | |
z = ((x - y*PI4A) - y*PI4B) - y*PI4C | |
} | |
var zz = z * z | |
if(zz > 1e-14){ | |
y = z + z*(zz*(((_tanP[0]*zz)+_tanP[1])*zz+_tanP[2])/((((zz+_tanQ[1])*zz+_tanQ[2])*zz+_tanQ[3])*zz+_tanQ[4])) | |
} else { | |
y = z | |
} | |
if(j&2 == 2){ | |
y = -1 / y | |
} | |
if(sign){ | |
y = -y | |
} | |
return y | |
} | |
pi=Math.Pi | |
console.log(tan(pi/2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment