You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.0 KiB
119 lines
3.0 KiB
#ifndef YDWELogarithmIncluded
|
|
#define YDWELogarithmIncluded
|
|
|
|
#include "YDWEBase.j"
|
|
|
|
library YDWELogarithm initializer onInit
|
|
|
|
globals
|
|
private real array base
|
|
endglobals
|
|
|
|
// Author : zyl910
|
|
// Modified by : c kuhn
|
|
// [private]用级数计算以e为底的对数
|
|
// Returns 0 if x <= 0
|
|
private function ln_taylor takes real x returns real
|
|
// ln( (1+x) / (1-x) ) = ln(1+x) - ln(1-x) = 2 * ( x + x^3 / 3 + x^5 / 5 + ... )
|
|
// x = (y-1) / (y+1)
|
|
// (0 < y < +∞, -1 < x < 1)
|
|
local real fRet = 0.
|
|
local real x2 // x*x
|
|
local real fCur
|
|
local real fDiv = 1.
|
|
|
|
if x > 0 then
|
|
set x = (x-1.) / (x+1.)
|
|
set x2 = x*x
|
|
loop
|
|
set fCur = fRet + x * 2. / fDiv
|
|
exitwhen fRet >= fCur and fRet <= fCur
|
|
set fRet = fCur
|
|
set x = x * x2
|
|
set fDiv = fDiv + 2.
|
|
endloop
|
|
endif
|
|
|
|
return fRet
|
|
endfunction
|
|
|
|
// Author : c kuhn
|
|
// 通过满二叉树特性快速找到大的部分
|
|
private function Log2 takes real x returns real
|
|
local real res = 0.
|
|
local real sign =1.
|
|
local real i = 64.
|
|
local real level = 32.
|
|
local real mid
|
|
local real temp
|
|
local real fac = 0.
|
|
local integer count = 6
|
|
|
|
if x>0 and (x<1 or x>1) then
|
|
if x<1 then
|
|
set sign = -1.
|
|
set x = 1. / x
|
|
endif
|
|
if x >= 2. then
|
|
set mid = base[7]
|
|
loop
|
|
set temp = x / mid
|
|
exitwhen temp >= 1. and temp < 2.
|
|
if x < mid then
|
|
set i = i - level
|
|
set mid = mid / base[count]
|
|
else
|
|
set i = i + level
|
|
set mid = mid * base[count]
|
|
endif
|
|
set level = level / 2.
|
|
set count = count - 1
|
|
endloop
|
|
set fac = i
|
|
set x = temp
|
|
endif
|
|
//根号2
|
|
if x > 1.4142135 then
|
|
set x = x / 1.4142135
|
|
set fac = fac + .5
|
|
endif
|
|
set res=sign*(fac+ln_taylor(x)*1.442695)
|
|
endif
|
|
|
|
return res
|
|
endfunction
|
|
|
|
// 以 10 为底的对数
|
|
// Returns 0 if x <= 0
|
|
function YDWELogarithmLg takes real x returns real
|
|
return Log2(x) * 0.3010300 // 1/log2(10) = 0.30102999566398119521373889472449
|
|
endfunction
|
|
|
|
// 以 e 为底的对数
|
|
// Returns 0 if x <= 0
|
|
function YDWELogarithmLn takes real x returns real
|
|
return Log2(x) * 0.6931472 // 1/log2(e) = 0.69314718055994530941723212145818
|
|
endfunction
|
|
|
|
// 以 任意数 为底的对数
|
|
function YDWELogarithmLog takes real a,real x returns real
|
|
if a<=0 or (a<=1 and a>=1) then
|
|
return 0.
|
|
endif
|
|
return Log2(x) / Log2(a)
|
|
endfunction
|
|
|
|
private function onInit takes nothing returns nothing
|
|
set base[1] = 2.
|
|
set base[2] = 4.
|
|
set base[3] = 16.
|
|
set base[4] = 256.
|
|
set base[5] = 65536.
|
|
//过大的数必须用乘法
|
|
set base[6] = 65536. * 65536. //2^32
|
|
set base[7] = base[6] * base[6] //2^64
|
|
endfunction
|
|
|
|
endlibrary
|
|
|
|
#endif /// YDWELogarithmIncluded
|
|
|