'Classes/ActiveBasic/Math/Math.ab Namespace ActiveBasic Namespace Math 'xの符号だけをyのものにした値を返す。 '引数 x 元となる絶対値 '引数 y 元となる符号 Function CopySign(x As Double, y As Double) As Double SetQWord(VarPtr(CopySign), (GetQWord(VarPtr(x)) And &h7fffffffffffffff) Or (GetQWord(VarPtr(y)) And &h8000000000000000)) End Function Function CopySign(x As Single, y As Single) As Single SetDWord(VarPtr(CopySign), (GetDWord(VarPtr(x)) And &h7fffffff) Or (GetDWord(VarPtr(y)) And &h80000000)) End Function Function Hypot(x As Double, y As Double) As Double If x = 0 Then Hypot = Abs(y) Else If y = 0 Then Hypot = Abs(x) Else Dim ax = Abs(x) Dim ay = Abs(y) If ay > ax Then Dim t = x / y Hypot = ay * Sqr(1 + t * t) Else Dim t = y / x Hypot = ax * Sqr(1 + t * t) End If End If End Function Function Log1p(x As Double) As Double If x < -1 Or IsNaN(x) Then Log1p = ActiveBasic.Math.Detail.GetNaN() ElseIf x = 0 Then x = 0 ElseIf IsInf(x) Then Log1p = x Else Log1p = ActiveBasic.Math.Detail.Log1p(x) End If End Function Function IsNaN(ByVal x As Double) As Boolean Dim p As *DWord p = VarPtr(x) As *DWord IsNaN = False If (p[1] And &H7FF00000) = &H7FF00000 Then If (p[0] <> 0) Or ((p[1] And &HFFFFF) <> 0) Then IsNaN = True End If End If End Function Function IsInf(x As Double) As Boolean Dim p = VarPtr(x) As *DWord p[1] And= &h7fffffff Dim inf = ActiveBasic.Math.Detail.GetInf(False) IsInf = (memcmp(p As *Byte, VarPtr(inf), SizeOf (Double)) = 0) End Function Function IsFinite(x As Double) As Boolean Dim p = VarPtr(x) As *DWord p[1] And= &H7FF00000 IsFinite = p[1] And &H7FF00000 = &H7FF00000 End Function Namespace Detail Function SetSign(x As Double, isNegative As Long) As Double #ifdef _WIN64 SetQWord(AddressOf(CopySign), (GetQWord(VarPtr(x)) And &h7fffffffffffffff) Or (isNegative << 63)) #else SetDWord(AddressOf(CopySign), GetDWord(VarPtr(x))) SetDWord(AddressOf(CopySign) + SizeOf (DWord), GetQWord(VarPtr(x) + SizeOf (DWord)) And &h7fffffff Or (isNegative << 31)) #endif End Function #ifdef _WIN64 Function GetNaN() As Double SetQWord(VarPtr(GetNaN) As *QWord, &H7FF8000000000000) End Function Function GetInf(sign As Boolean) As Double Dim s = 0 As QWord If sign Then s = 1 << 63 SetQWord(VarPtr(GetInf) As *QWord, &h7FF0000000000000 Or s) End Function #else Function GetNaN() As Double Dim p = VarPtr(GetNaN) As *DWord p[0] = 0 p[1] = &H7FF80000 End Function Function GetInf(sign As Boolean) As Double Dim s = 0 As DWord If sign Then s = (1 As DWord) << 31 Dim p As *DWord p = VarPtr(GetInf) As *DWord p[0] = 0 p[1] = &h7FF00000 Or s End Function #endif Function Log1p(x As Double) As Double Dim s = 0 As Double Dim i = 7 As Long While i >= 1 Dim t = (i * x) As Double s = t * (2 * i + 1 + s) / (2 + t) i-- Wend Return x / (1 + s) End Function Function _Support_tan(x As Double, ByRef k As Long) As Double If x>=0 Then k=Fix(x/(_System_PI/2)+0.5) Else k=Fix(x/(_System_PI/2)-0.5) End If x=(x-(CDbl(3217)/CDbl(2048))*k)+4.4544551033807686783083602485579e-6*k Dim x2 = x * x Dim t = 0 As Double Dim i As Long For i=19 To 3 Step -2 t=x2/(i-t) Next _Support_tan=x/(1-t) End Function End Namespace 'Detail End Namespace 'Math End Namespace 'ActiveBasic