summaryrefslogtreecommitdiff
path: root/lace.rb
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lace.rb82
1 files changed, 82 insertions, 0 deletions
diff --git a/lace.rb b/lace.rb
index ef9a97e..b5aebf1 100644
--- a/lace.rb
+++ b/lace.rb
@@ -1,7 +1,89 @@
1require "bigdecimal"
1require "set" 2require "set"
2 3
3module Lace 4module Lace
4 5
6 PREFIXES = {
7 "femto" => 10**-15,
8 "f" => 10**-15,
9 "pico" => 10**-12,
10 "p" => 10**-12,
11 "nano" => 10**-9,
12 "n" => 10**-9,
13 "micro" => 10**-6,
14 "u" => 10**-6,
15 "ยต" => 10**-6,
16 "milli" => 10**-3,
17 "m" => 10**-3,
18 "" => 10**0,
19 "kilo" => 10**3,
20 "k" => 10**3,
21 "mega" => 10**6,
22 "M" => 10**6,
23 }
24
25 def self.number(num)
26 num = num.to_s
27 PREFIXES.each do | p, d |
28 if num =~ /^(.+)#{p}$/i
29 begin
30 num = BigDecimal($1) * d
31 break
32 rescue ArgumentError
33 end
34 end
35 end
36 num = BigDecimal(num) unless num.instance_of?(BigDecimal)
37 return "0" if num == 0
38 prefix = "f"
39 div = PREFIXES["f"]
40 PREFIXES.each do | p, d |
41 if num.abs >= d and d >= div and (d > div or p.size < prefix.size or (p.size == prefix.size and p > prefix))
42 prefix = p
43 div = d
44 end
45 end
46 num /= div
47 num = num.to_s("F")
48 num.sub!(/\.0$/, "")
49 return "#{num}#{prefix}"
50 end
51
52 E3 = [10, 22, 47]
53 E6 = E3 + [15, 33, 68]
54 E12 = E6 + [12, 18, 27, 39, 56, 82]
55 E24 = E12 + [11, 13, 16, 20, 24, 30, 36, 43, 51, 62, 75, 91]
56
57 E48 = [100, 105, 110, 115, 121, 127, 133, 140, 147, 154, 162, 169, 178, 187, 196, 205, 215, 226, 237, 249, 261, 274, 287, 301, 316, 332, 348, 365, 383, 402, 422, 442, 464, 487, 511, 536, 562, 590, 619, 649, 681, 715, 750, 787, 825, 866, 909, 953]
58 E96 = E48 + [102, 107, 113, 118, 124, 130, 137, 143, 150, 158, 165, 174, 182, 191, 200, 210, 221, 232, 243, 255, 267, 280, 294, 309, 324, 340, 357, 374, 392, 412, 432, 453, 475, 499, 523, 549, 576, 604, 634, 665, 698, 732, 768, 806, 845, 887, 931, 976]
59 E192 = E96 + [101, 104, 106, 109, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 142, 145, 149, 152, 156, 160, 164, 167, 172, 176, 180, 184, 189, 193, 198, 203, 208, 213, 218, 223, 229, 234, 240, 246, 252, 258, 264, 271, 277, 284, 291, 298, 305, 312, 320, 328, 336, 344, 352, 361, 370, 379, 388, 397, 407, 417, 427, 437, 448, 459, 470, 481, 493, 505, 517, 530, 542, 556, 569, 583, 597, 612, 626, 642, 657, 673, 690, 706, 723, 741, 759, 777, 796, 816, 835, 856, 876, 898, 920, 942, 965, 988]
60
61 def self.nearest(num, set)
62 return BigDecimal(0) if num == 0
63 base = set.min
64 exp = Math.log10(base).round
65 numexp = Math.log10(num).floor
66 num = num * 10**(exp-numexp)
67 candidate = nil
68 delta = Float::INFINITY
69 set.each do | c |
70 d = (num - c).abs
71 if d < delta
72 candidate = c
73 delta = d
74 end
75 end
76 return BigDecimal(candidate * 10**(numexp-exp), exp+1)
77 end
78
79 def self.e3(num); nearest(num, E3); end
80 def self.e6(num); nearest(num, E6); end
81 def self.e12(num); nearest(num, E12); end
82 def self.e24(num); nearest(num, E24); end
83 def self.e48(num); nearest(num, E48); end
84 def self.e96(num); nearest(num, E96); end
85 def self.e192(num); nearest(num, E192); end
86
5 class Netlist 87 class Netlist
6 88
7 attr_reader :components 89 attr_reader :components