g | x | w | all
Bytes Lang Time Link
192JavaScript Node.js250923T135618ZFhuvi
172APLNARS250910T113545ZRosario
08805AB1E250910T074207ZKevin Cr
080Jelly250911T230504ZJonathan
167Ruby250910T140731ZLevel Ri
222R250910T155826ZM--
199JavaScript ES6250909T103734ZArnauld
191Retina 0.8.2250910T150544ZNeil
108Charcoal250909T234352ZNeil
300Google Sheets250909T222604Zdoubleun

JavaScript (Node.js), 192 bytes

I tried a different approach than Arnauld's JS answer, and it turned out pretty well!

r=>t=>[(s=Math.floor(r*100)+"0")[0],s[1],(l=s.length)<3?0:l-5,t<1?3+(1/t+6)**.5|0:t>4?t%4-3:t].map(n=>"NoneSilverGoldBlackBrownRedOrangeYellowGreenBlueVioletGreyWhite".match(/.[a-z]+/g)[+n+3])

Try it online!


The goal was to avoid scientific notation, and use the length of the string to obtain the Multiplier.
The first and second characters correspond to the two Digits.
The Tolerance is converted through conditions and computations to avoid the length of a lookup string.

APL(NARS), 172 chars

{a←(+\a∊⎕A)⊂a←'NoneSilverGoldBlackBrownRedOrangeYellowGreenBlueVioletGreyWhite'⋄b←20,10,5,0,(⍳4),.5,.25,.10,.05⋄k←⌊⍺÷10*r←⌊10⍟(⍺÷10)+0=⍺⋄a[4+⌊k÷10],a[4+10∣k],a[4+r],a[b⍳⍵]}

Input in the left in ⍺ the resistor value, and in the right in the ⍵ the percentage of tolerance.

test:

 f←{a←(+\a∊⎕A)⊂a←'NoneSilverGoldBlackBrownRedOrangeYellowGreenBlueVioletGreyWhite'⋄b←20,10,5,0,(⍳4),.5,.25,.10,.05⋄k←⌊⍺÷10*r←⌊10⍟(⍺÷10)+0=⍺⋄a[4+⌊k÷10],a[4+10∣k],a[4+r],a[b⍳⍵]}
 80000000000 f 1
Grey Black White Brown 
 0 f 1 
Black Black Black Brown 
 0.63 f 0.05
Blue Orange Silver Grey 
  84000 f 1
Grey Yellow Orange Brown 
  0 f 4
Black Black Black Yellow 

05AB1E, 88 bytes

Ð.0м0.øsgΘÛ2∍DŠ/¹_+т*T.nòͪ•c€µÖ:Ëjøz®º€8¡•₄;в20/Ikª”ƒÏŽÌ†¾›ÈŠÛˆ¨‡— Violet°¯„¸Šª‹ßˆ°”#sè

Try it online or verify all test cases.

Explanation:

Ð                # Triplicate the first (implicit) input-resistance
 .0              # Push ".0"
   м             # Remove a potential "." and all "0"s from the next copy
    0.ø          # Surround it with a leading/trailing 0
       s         # Swap to get the input-resistance at the top again
        g        # Pop and push its length
         Θ       # Do an ==1 check (1 if 1; 0 otherwise)
          Û      # Trim those leading digits from the string
                 # (aka, trim the leading added 0 if the input-length isn't 1)
           2∍    # Shorten the length to a pair
                 # (aka, trim the trailing added 0 if the input contains two non-0 digits)
                 # (we now have a string of the two Digits)
D                # Duplicate this string-pair of digits
 Š               # Triple-swap a,b,c to c,a,b
  /              # Divide the remaining resistance by this pair of digits
                 # (we now have the Multiplier)
   ¹             # Push the first input-resistance again
    _            # Do an ==0 check (1 if 0; 0 otherwise)
     +           # Add that to the Multiplier-value
   т*            # Multiply by 10
     T.n         # Logarithm of 10
        ò        # Round to the nearest integer (for floating point inaccuracies)
         Í       # Subtract 2
          ª      # Convert the string-pair to a pair of digits,
                 # and append this value to it
•c€µÖ:Ëjøz®º€8¡• # Push compressed integer 742226680000078203187562525100400
  ₄;             # Push 500 (1000 halved)
    в            # Convert the large integer to a base-500 list:
                 #  [3,20,40,60,80,10,5,2,1,0,100,200,400]
     20/         # Divide each by 20:
                 #  [0.15,1,2,3,4,0.5,0.25,0.1,0.05,0,5,10,20]
        Ik       # Get the 0-based index of the second input-tolerance in this list
          ª      # Append it to the earlier triplet
”ƒÏŽÌ†¾›ÈŠÛˆ¨‡— Violet°¯„¸Šª‹ßˆ°”
                 # Push dictionary string "Black Brown Red Orange Yellow Green Blue Violet Grey White None Silver Gold"
 #               # Split it on spaces
  s              # Swap so the earlier quartet is at the top of the stack again
   è             # Get the strings at those indices
                 # (where the -1 and -2 are the last and next to last values)
                 # (after which the result is output implicitly)

See this 05AB1E tip of mine (sections How to use the dictionary?, How to compress large integers?, and How to compress integer lists?) to understand why •c€µÖ:Ëjøz®º€8¡• is 742226680000078203187562525100400; •c€µÖ:Ëjøz®º€8¡•₄;в is [3,20,40,60,80,10,5,2,1,0,100,200,400]; and ”ƒÏŽÌ†¾›ÈŠÛˆ¨‡— Violet°¯„¸Šª‹ßˆ°” is "Black Brown Red Orange Yellow Green Blue Violet Grey White None Silver Gold".

Jelly, 80 bytes

tŻŻ+3ṫ-;ċ
×ȷDç0ṣ13U-¦j12;“ṀdxÞ(<P½¦£¢‘÷20¤i⁹¤ị“!-WƓ®ḲTọnṾȦẊḟeż&)ÇạøN5ḤtḣḲXƓȧȯ»Ḳ¤

A dyadic Link that accepts the resistance on the left and the tolerance on the right and yields the band colours as a list of four lists of characters.

Try it online! Or see the test-suite.

How?

tŻŻ+3ṫ-;ċ - Helper Link: D=Digits of 1000×R, Y=0
t         - trim {Y}s from {D}
 ŻŻ       - prefix with two zeros
   +3     - add three to each of these
     ṫ-   - tail from 1-index -1 (keep the last two)
       ;ċ - concatenate the count of zeros in {D}

×ȷDç0ṣ13U-¦j12;“...‘÷20¤i⁹¤ị“...»Ḳ¤ - Main Link: R, T
×ȷ                                  - multiply {R} by 1000 -> 1000R
  D                                 - get the decimal digits of that -> D
   ç0                               - call the Helper Link - f(D, 0)
     ṣ13U-¦j12                        handling edge-case R = (d×10 + 0) × 10^9:
     ṣ13                            -   split at 13s
        U-¦                         -   reverse the penultimate chunk
           j12                      -   join with 12s
                                      -> [d1+3, d2+3, MultiplierIndex]
                          ¤         - nilad followed by link(s) as a nilad:
                       ¤            -   nilad followed by link(s) as a nilad:
               “...‘                -     code-page indices
                                          -> [200,100,120,20,40,60,80,10,5,2,1] 
                    ÷20             -     divide by twenty
                                          -> [10,5,6,1,2,3,4,0.5,0.25,0.1,0.05]
                        i⁹          -   1-index of {T} in that, or 0 if not found (T=20)
              ;                     - concatenate
                                      -> [d1+2, d2+2, MultiplierIndex, ThresholdIndex]
                           ị        - 1-index, cyclically, into...
                                  ¤ - ...nilad followed by link(s) as a nilad:
                            “...»   -   "Silver Gold Black Brown Red Orange Yellow Green Blue Violet Grey White None"
                                 Ḳ  -   split at spaces

Ruby, 170 167 bytes

->a,b{[0,2,9,13].map{|i|%w{Black Brown Red Orange Yellow Green Blue Violet Grey White None Silver Gold}[("%e #{"873;62:<154"[b*19%11].ord-48}"%(a/10))[i,i/4+1].to_i]}}

Try it online!

Eliminated variable c, used value directly. Changed decoding of tolerance colour from a magic number to a magic string. New perfect hash b*19%11 is 1 byte shorter in Ruby than a port of @Arnauld's approach but gives some floating point numbers. These are however automatically truncated to integers when used for lookup in the string.

Ruby, 176 bytes

->a,b{c="%e #{0x1234CAF5FB6F78>>(b*13%14).to_i*4&15}"%a/=10
[0,2,9,13].map{|i|%w{Black Brown Red Orange Yellow Green Blue Violet Grey White None Silver Gold}[c[i,i/4+1].to_i]}}

Try it online!

A function taking two numbers as arguments and returning an array of strings containing colours.

We generate a string like the below with the exponential representation of a to which we append an integer representing the correct colour of the tolerance stripe from b.

We then map through the indices [0,2,9,13] of this string, pick out an appropriate number of characters i/4+1, convert this to an integer and lookup the correct colour.

"0.000000e+00 4"
["Black", "Black", "Black", "Yellow"]
"8.400000e+03 1"
["Grey", "Yellow", "Orange", "Brown"]
"6.300000e-02 8"
["Blue", "Orange", "Silver", "Grey"]

Note that None, Silver, Gold appear in the code in reverse order than in the table in the question. This is because Ruby wraps negative indices to the end of the array. Hence -02 in the example above becomes "Silver" as this is the second last element.

There are probably better ways of decoding the index of the tolerance stripe into an integer that matches the colour scheme used by other stripes. This is the first way I came up with. I may get back to it later.

R, 268 243 227* 222 bytes

\(r,t,s=strtoi(el(strsplit(sprintf("%.1e",r),"[.e]"))),v=s[3])c(colors()[c(24,32,552,498,652,254,26,640,260,1,142)],"silver","none")[c(s[-3]+1,`if`(r<1e-9,1,13*(v<0)+v),c(2:9,11:13)[match(t,c(1:4,.5,.25,.1,.05,5,10,20))])]

Attempt This Online!

* 16 bytes saved by pajonk.

JavaScript (ES6), 199 bytes

-1 thanks to @Neil

Expects (r)(t) and returns an array of 4 strings.

r=>t=>[([[x,,y],e]=r.toExponential(1).split`e`,z=r>=.1)*x,z?y:x,e-z,"0x"+"0A9C1864537"[t*20%52%11]-2].map(n=>"SilverGoldBlackBrownRedOrangeYellowGreenBlueVioletGreyWhiteNone".match(/.[a-z]+/g)[+n+2])

Try it online!

Color list

To make it easier to encode multipliers, the color list is reorganized as follows:

Resistance value

We normalize the resistance value \$r\$ in exponential notation with one fraction digit and map the result to the variables \$x\$, \$y\$, \$e\$ (first significant digit, next digit and signed exponent respectively).

For instance:

84000 --> "8.4e+4" --> x = "8", y = "4", e = "+4"

It's encoded as:

For each of these values, the actual color index is obtained by adding \$2\$.

Tolerance

The tolerance is first turned into an integer by multiplying it by \$20\$, then reduced to a lookup index in \$[0\dots10]\$ by applying the modulo chain \$(x \bmod 52)\bmod 11\$.

The lookup string "0A9C1864537" stores the color indexes in hexadecimal.

Color Tolerance ×20 mod 52 mod 11 Color index
Brown 1 20 20 9 0x3
Red 2 40 40 7 0x4
Orange 3 60 8 8 0x5
Yellow 4 80 28 6 0x6
Green 0.5 10 10 10 0x7
Blue 0.25 5 5 5 0x8
Violet 0.1 2 2 2 0x9
Grey 0.05 1 1 1 0xA
Gold 5 100 48 4 0x1
Silver 10 200 44 0 0x0
None 20 400 36 3 0xC

Commented

r =>                   // outer function taking r
t =>                   // inner function taking t
[                      //
  (                    //
    [[x,,              // x = 1st significant digit of r as a character
          y],          // y = next digit as a character
              e] =     // e = signed exponent string (e.g. "+2")
    r.toExponential(1) // extracted from r.toExponential(1) ...
    .split`e`,         // ... split on 'e'
    z = r >= .1        // set z to true if r is greater or equal to 0.1
  ) * x,               // 1) use x if z is set, or 0 otherwise
  z ? y                // 2) use y if z is set,
    : x,               //    or x otherwise
  e - z,               // 3) use e - z
  "0x" +               // 4) hexadecimal prefix
  "0A9C1864537"[       //    read this lookup string at ...
    t * 20 % 52 % 11   //    ... the relevant index computed from t
  ] - 2                //    subtract 2
].map(n =>             // for each value n computed above:
  "SilverGold...None"  //   color lookup string
  .match(              //   split by words
    /.[a-z]+/g         //   (using title case)
  )[+n + 2]            //   take the entry at index n+2
)                      // end of map()

Retina 0.8.2, 191 bytes

^0 
00 
 
12$*0 
0?\.(.{12})0*
$1
^(.)(.)(0{12})?(0*)
$1 $2 $.4
20
None
11|\b5$
Gold
10
Silver
9
White
8|0.05
Grey
7|0.1
Violet
6|0.25
Blue
5|0.5
Green
4
Yellow
3
Orange
2
Red
1
Brown
0
Black

Try it online! Link includes test cases. Explanation:

^0 
00 

Add an extra 0 to a zero input so that the exponent comes out correct.

 
12$*0 
0?\.(.{12})0*
$1
^(.)(.)(0{12})?(0*)
$1 $2 $.4

Multiply by 10¹², then capture the first two digits and reduce the exponent modulo 12. This conveniently maps -2 to 10 for Silver.

20
None
11|\b5$
Gold
10
Silver
9
White
8|0.05
Grey
7|0.1
Violet
6|0.25
Blue
5|0.5
Green
4
Yellow
3
Orange
2
Red
1
Brown
0
Black

Map each value to its colour, except that Gold is 5(%) tolerance instead of Green, and Grey to Green also match their respective tolerances.

Charcoal, 108 bytes

≔﹪%.1e∕NχθE⟦§θ⁰§θ²⊟⪪θe⌕⪪”‴|“V¶!⊘π▶α…qêZY‽≕P›” S⟧⭆§⪪”↶±!γ$~∧‖!\↧F%1/⁶fL\`κ↖!↶Φ#⁵ïδDy◨ ?jFNNωπbe!V⍘¬y↷” Iι⎇μλ↥λ

Try it online! Link is to verbose version of code. Explanation:

≔﹪%.1e∕Nχθ

Divide the first input by 10 and then convert it to exponential notation with one digit after the decimal point, e.g. 84000 converts to 8.4e+03.

E⟦§θ⁰§θ²⊟⪪θe

Map over the first character, the third character and the exponent, and also...

⌕⪪”...” S⟧

... looking up the tolerance in a compressed list split on spaces, ...

⭆§⪪”...” Iι⎇μλ↥λ

... look up each value in the compressed lowercase list of colours and uppercase the first character (this is still 3 bytes shorter overall than using proper case in the list of colours).

The compressed list of colours ends with none silver gold as this allows for cyclic indexing for exponents of -1 and -2.

Google Sheets, 300 bytes

=sort(let(f,lambda(k,n,xlookup(k,n,tocol(split("Black0Brown0Red0Orange0Yellow0Green0Blue0Violet0Grey0White0Gold0Silver0None",0)))),g,lambda(n,index(split(text(A1,"0.0#e+0"),".e"),n)),{f({g(1),g(2),if(g(3)=-1,11,g(3)-(g(1)>0))},row(1:13)-1),f(B1,tocol(split("919293949.59.259.19.05995910920",9,,)))}))

Put resistance in A1 and tolerance in B1. Outputs four strings.

screenshot

This matches all current test cases but doesn't observe what's said in the question's comments.

Ungolfed:

=arrayformula(let(
  c, tocol(split("Black0Brown0Red0Orange0Yellow0Green0Blue0Violet0Grey0White0Gold0Silver0None", 0)),
  m, tocol(split(",1,2,3,4,.5,.25,.1,.05,,5,10,20", ",",,)),
  i, sequence(13) - 1,
  f, lambda(k, n, xlookup(k, n, c)),
  g, lambda(n, index(split(text(A1, "0.0#e+0"), ".e"), n)),
  { f({ g(1), g(2), if(g(3) = -1, 11, g(3) - (g(1) > 0)) }, i), f(B1, m) }
))