--- /dev/null
+#!/usr/bin/nickle
+#
+# Compute resistor dividers
+#
+#
+
+if (dim(argv) != 3) {
+ File::fprintf(stderr, "usage: %s <input voltage> <output voltage>\n", argv[0]);
+ exit(1);
+}
+
+real input = atof(argv[1]);
+real output = atof(argv[2]);
+
+real[...] resistors = {
+ 10.0, 10.2, 10.5, 10.7, 11.0, 11.3, 11.5, 11.8, 12.1, 12.4, 12.7, 13.0,
+ 13.3, 13.7, 14.0, 14.3, 14.7, 15.0, 15.4, 15.8, 16.2, 16.5, 16.9, 17.4,
+ 17.8, 18.2, 18.7, 19.1, 19.6, 20.0, 20.5, 21.0, 21.5, 22.1, 22.6, 23.2,
+ 23.7, 24.3, 24.9, 25.5, 26.1, 26.7, 27.4, 28.0, 28.7, 29.4, 30.1, 30.9,
+ 31.6, 32.4, 33.2, 34.0, 34.8, 35.7, 36.5, 37.4, 38.3, 39.2, 40.2, 41.2,
+ 42.2, 43.2, 44.2, 45.3, 46.4, 47.5, 48.7, 49.9, 51.1, 52.3, 53.6, 54.9,
+ 56.2, 57.6, 59.0, 60.4, 61.9, 63.4, 64.9, 66.5, 68.1, 69.8, 71.5, 73.2,
+ 75.0, 76.8, 78.7, 80.6, 82.5, 84.5, 86.6, 88.7, 90.9, 93.1, 95.3, 97.6,
+ 100.0,
+};
+
+real divider(real input, real ra, real rb)
+{
+ return input * rb / (ra + rb);
+}
+
+real find_ra(real input, real output, real rb)
+{
+ real ra;
+ /* output = input * rb / (ra + rb)
+ * output / (input * rb) = 1 / (ra + rb)
+ * (input * rb) / output = ra + rb
+ * (input * rb) / output - rb = ra
+ */
+
+ return (input * rb) / output - rb;
+}
+
+real error(real input, real output, real ra, real rb)
+{
+ real actual = divider(input, ra, rb);
+
+ real e = abs(actual - output);
+ return e;
+}
+
+real closest_standard(real ohms)
+{
+ real exp = floor(log10(ohms));
+ real mul = pow(10,exp + 1);
+ real search = ohms * mul;
+
+ for (int i = 0; i < dim(resistors)-1; i++) {
+ if (resistors[i] <= search && search <= resistors[i+1])
+ if (abs(resistors[i] - search) < abs(resistors[i]+1 - search)) {
+ return resistors[i] / mul;
+ } else {
+ return resistors[i+1] / mul;
+ }
+ }
+ return 0;
+}
+
+void find_divider(real input, real output)
+{
+ real best_a, best_b;
+ real best_error = -1;
+
+ for (int i = 0; i < dim(resistors); i++) {
+ real rb = resistors[i];
+ real ra_ideal = find_ra(input, output, rb);
+ real ra_actual = closest_standard(ra_ideal);
+ real e = error(input, output, ra_actual, rb);
+ if (best_error < 0 || e < best_error) {
+ best_a = ra_actual;
+ best_b = rb;
+ best_error = e;
+ }
+ }
+ printf("input: %g ra: %g rb: %g output %g\n", input, best_a, best_b, divider(input, best_a, best_b));
+}
+
+find_divider(input, output);