diff options
| author | Julian Blake Kongslie | 2022-05-17 11:29:44 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-05-17 11:29:44 -0700 |
| commit | 8a8651404bd8ed187bcaedfef2948e7835aea318 (patch) | |
| tree | fe0cc338ff824cece580b2d47d7d5d6cc623843e /lace.rb | |
| parent | More unicode. (diff) | |
| download | lace-8a8651404bd8ed187bcaedfef2948e7835aea318.tar.xz | |
Automatically finding E-series matches and metric prefixes
Diffstat (limited to '')
| -rw-r--r-- | lace.rb | 82 |
1 files changed, 82 insertions, 0 deletions
| @@ -1,7 +1,89 @@ | |||
| 1 | require "bigdecimal" | ||
| 1 | require "set" | 2 | require "set" |
| 2 | 3 | ||
| 3 | module Lace | 4 | module 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 |
