This repository has been archived by the owner on May 4, 2023. It is now read-only.
forked from rubinius/rubinius
/
math19.rb
85 lines (71 loc) · 1.7 KB
/
math19.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# -*- encoding: us-ascii -*-
module Math
FactorialTable = [
1.0,
1.0,
2.0,
6.0,
24.0,
120.0,
720.0,
5040.0,
40320.0,
362880.0,
3628800.0,
39916800.0,
479001600.0,
6227020800.0,
87178291200.0,
1307674368000.0,
20922789888000.0,
355687428096000.0,
6402373705728000.0,
121645100408832000.0,
2432902008176640000.0,
51090942171709440000.0,
1124000727777607680000.0
]
def cbrt(x)
x = Rubinius::Type.coerce_to_float x
end
def gamma(x)
x = Rubinius::Type.coerce_to_float x
return Float::INFINITY if x == 0.0
return Float::NAN if x.nan?
if sign = x.infinite?
raise DomainError, "gamma" if sign == -1
return Float::INFINITY
end
FFI::MemoryPointer.new :double do |integral|
fractional = FFI::Platform::Math.modf x, integral
int = integral.read_double.to_i
if fractional == 0.0
raise DomainError, "gamma" if int < 0
return FactorialTable[int - 1] if int <= FactorialTable.size
end
end
FFI::Platform::Math.tgamma x
end
def lgamma(x)
x = Rubinius::Type.coerce_to_float x
if sign = x.infinite?
raise DomainError, "lgamma" if sign == -1
return [Float::INFINITY, 1]
end
FFI::MemoryPointer.new :int do |sign|
result = FFI::Platform::Math.lgamma_r x, sign
[result, sign.read_int]
end
end
def log(x, base=undefined)
x = Rubinius::Type.coerce_to_float x
raise DomainError, 'log' unless x >= 0.0
return -Float::INFINITY if x == 0.0
y = FFI::Platform::Math.log x
unless base.equal? undefined
base = Rubinius::Type.coerce_to_float base
y /= log(base)
end
y
end
end