github.com/remobjects/goldbaselibrary@v0.0.0-20230924164425-d458680a936b/Source/Gold/Math.pas (about) 1 namespace go.math; 2 3 uses 4 go.builtin; 5 6 type 7 {$IF ECHOES}PlatformMath = System.Math;{$ENDIF} 8 {$IF ISLAND}PlatformMath = RemObjects.Elements.System.Math;{$ENDIF} 9 10 11 12 13 const 14 MaxInt8 = 1 shl 7 - 1; public; 15 MinInt8 = -1 shl 7; public; 16 MaxInt16 = 1 shl 15 - 1; public; 17 MinInt16 = -1 shl 15; public; 18 //MaxInt32 = 1 shl 31 - 1; public; 19 MaxInt32 = 2147483647; public; 20 MinInt32 = -1 shl 31; public; 21 MaxInt64 = 1 shl 63 - 1; public; 22 MinInt64 = -1 shl 63; public; 23 MaxUint8 = 1 shl 8 - 1; public; 24 MaxUint16 = 1 shl 16 - 1; public; 25 MaxUint32 = 1 shl 32 - 1; public; 26 MaxUint64 = 1 shl 64 - 1; public; 27 28 29 method Trunc(x: Double): Double; public; 30 begin 31 {$IFDEF ECHOES} 32 exit System.Math.Truncate(x); 33 {$ELSE} 34 exit RemObjects.Elements.System.Math.Truncate(x); 35 {$ENDIF} 36 end; 37 38 method NaN(): Double; public; 39 begin 40 exit Double.NaN; 41 end; 42 43 method IsInf(v: Double; sign: Integer): Boolean; public; 44 begin 45 if sign < 0 then 46 exit Double.IsNegativeInfinity(v); 47 if sign > 0 then 48 exit Double.IsPositiveInfinity(v); 49 exit Double.IsInfinity(v); 50 end; 51 52 method IsNaN(v: Double): Boolean; public; 53 begin 54 exit Double.IsNaN(v); 55 end; 56 57 method Abs(v: Double): Double; public; 58 begin 59 exit PlatformMath.Abs(v); 60 end; 61 62 method Sqrt(v: Double): Double; public; inline; 63 begin 64 exit PlatformMath.Sqrt(v); 65 end; 66 67 68 method Inf(sign: Integer): Double; public;unsafe; 69 begin 70 if sign < 0 then 71 exit Double.NegativeInfinity; 72 exit Double.PositiveInfinity 73 end; 74 75 method Float32bits(f: Single): uint32; public;unsafe; 76 begin 77 ^Single(@result)^ := f; 78 end; 79 80 method Float32frombits(b: uint32): Single; public; unsafe; 81 begin 82 ^uint32(@Result)^ := b; 83 end; 84 85 method Float64bits(f: Double): uint64; public;unsafe; 86 begin 87 ^Double(@result)^ := f; 88 end; 89 90 method Float64frombits(b: uint64): Double; public; unsafe; 91 begin 92 ^uint64(@Result)^ := b; 93 end; 94 95 method Log(x: Double): Double; public; 96 begin 97 exit PlatformMath.Log(x); 98 end; 99 100 method Exp(x: Double): Double; public; 101 begin 102 exit PlatformMath.Exp(x); 103 end; 104 105 method Floor(x: Double): Double; public; 106 begin 107 exit PlatformMath.Floor(x); 108 end; 109 110 method Ceil(x: Double): Double; public; 111 begin 112 exit PlatformMath.Ceiling(x); 113 end; 114 115 method Ldexp(frac: Double; aexp: Integer): Double; public; 116 begin 117 exit PlatformMath.Pow(2, aexp) * frac; 118 end; 119 120 method Frexp(value: Double): tuple of (Double, Integer); public; 121 begin 122 {$IF ISLAND} 123 var bits: int64 := Convert.ToInt64(value); 124 {$ELSEIF ECHOES} 125 var bits: int64 := BitConverter.DoubleToInt64Bits(value); 126 {$ENDIF} 127 var realMant: Double := 1.0; 128 var exponent: Integer; 129 var resmmantissa: Double; 130 131 if Double.IsNaN(value) or 132 (value + value = value) or 133 Double.IsInfinity(value) then begin 134 exponent := 0; 135 resmmantissa := value; 136 end else begin 137 var neg := bits < 0; 138 exponent := ((bits shr 52) and $7ff); 139 var mantissa := bits and $fffffffffffff; 140 141 if(exponent = 0) then begin 142 inc(exponent); 143 end 144 else begin 145 mantissa := mantissa or (int64(1) shl 52); 146 end; 147 148 // bias the exponent - actually biased by 1023. 149 // we are treating the mantissa as m.0 instead of 0.m 150 // so subtract another 52. 151 exponent := exponent - 1075; 152 realMant := mantissa; 153 154 // normalize 155 while(realMant > 1.0) do begin 156 mantissa := mantissa shr 11; 157 realMant := realMant / 2.0; 158 inc(exponent); 159 end; 160 161 if(neg) then begin 162 realMant := realMant * -1; 163 end; 164 165 resmmantissa := realMant; 166 end; 167 exit (resmmantissa, exponent); 168 end; 169 170 method Log2(d: Double): Double; 171 begin 172 {$IF ISLAND} 173 exit PlatformMath.Log2(d); 174 {$ELSEIF ECHOES} 175 exit PlatformMath.Log(d, 2); 176 {$ENDIF} 177 end; 178 179 method Signbit(d: Double): Boolean; 180 begin 181 exit d < 0; 182 end; 183 184 // 185 // 186 // 187 188 method Asin(x: float64): float64; public; inline; 189 begin 190 result := PlatformMath.Asin(x); 191 end; 192 193 method Asinh(x: float64): float64; public; inline; 194 begin 195 result := PlatformMath.Log(x + PlatformMath.Sqrt(x * x + 1)) // via https://stackoverflow.com/questions/2840798/c-sharp-math-class-question/2840824 196 end; 197 198 method Atan(x: float64): float64; public; inline; 199 begin 200 result := PlatformMath.Atan(x); 201 end; 202 203 method Atan2(y, x: float64): float64; public; // via https://en.wikipedia.org/wiki/Atan2 204 begin 205 if (x > 0) or (y ≠ 0) then begin 206 result := 2 * Atan( y / (Sqrt(x*x + y*y) + x)); 207 end 208 else if (x < 0) and (y = 0) then begin 209 result := PlatformMath.PI; 210 end 211 else begin 212 result := Double.NaN; 213 end; 214 end; 215 216 method Copysign(x, y: float64): float64; public; 217 begin 218 result := if y > 0 then PlatformMath.Abs(x) else -PlatformMath.Abs(x); 219 end; 220 221 method Cos(x: float64): float64; public; inline; 222 begin 223 result := PlatformMath.Cos(x); 224 end; 225 226 method Cosh(x: float64): float64; public; inline; 227 begin 228 result := PlatformMath.Cosh(x); 229 end; 230 231 method Hypot(p, q: float64): float64; public; inline; 232 begin 233 result := PlatformMath.Sqrt(p * p + q * q); 234 end; 235 236 method Pow(x, y: float64): float64; public; inline; 237 begin 238 result := x ** y; 239 end; 240 241 method Pow10(n: int): float64; public; inline; 242 begin 243 result := 10 ** n; 244 end; 245 246 method Sin(x: float64): float64; public; inline; 247 begin 248 result := PlatformMath.Sin(x); 249 end; 250 251 method Sincos(x: float64): tuple of (sin: float64, cos: float64); public; inline; 252 begin 253 result := (Sin(x), Cos(x)); 254 end; 255 256 method Sinh(x: float64): float64; public; inline; 257 begin 258 result := PlatformMath.Sinh(x); 259 end; 260 261 end.