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
|
# File 'lib/propr/random/float.rb', line 5
def random(options = {}, m = Propr::Random)
min = (options[:min] || -Float::INFINITY).to_f
max = (options[:max] || Float::INFINITY).to_f
min_ = if min.finite? then min else -Float::MAX end
max_ = if max.finite? then max else Float::MAX end
range = max_.to_i - min_.to_i
center = options.fetch(:center, :mid)
center =
case center
when :min then min
when :max then max
when :mid
if (max_ - min_).finite?
min_ + (max_ - min_).fdiv(2)
else
(min_ + max_).fdiv(2)
end
when Numeric
raise ArgumentError,
"center < min" if center < min
raise ArgumentError,
"center > max" if center > max
center
else raise ArgumentError,
"center must be :min, :mid, :max, or min <= Integer <= max"
end
m.bind(m.rand(range)) do |whole|
m.bind(m.rand) do |fraction|
value = BigDecimal(min_, 15) + whole
value += BigDecimal(fraction, 0)
center = BigDecimal(center, 0)
m.bind(m.scale(value, range, center)) do |d|
m.unit(d.to_f)
end
end
end
end
|