1#include <stdio.h>
2#include <stdbool.h>
3
4#define uint64 long long unsigned
5#define int64 long long
6
7static void
8nearest_powers(uint64 value, uint64 *lower, uint64 *upper)
9{
10        uint64 power = 1UL << 12;
11	if (lower)
12	        *lower = power;
13        while (value >= power) {
14		if (lower)
15	             *lower = power;
16             power <<= 1;
17        }
18	if (upper)
19	       *upper = power;
20}
21
22
23int64 sols[5];
24int solCount;
25int64 props[5];
26
27static void
28find_nearest(uint64 value, int iteration)
29{
30	if (iteration > 4 || (iteration + 1) >= solCount)
31		return;
32	uint64 down, up;
33	int i;
34	nearest_powers(value, &down, &up);
35	props[iteration] = down;
36	if (value - down < 0x100000) {
37		for (i=0; i<=iteration; i++)
38			sols[i] = props[i];
39		solCount = iteration + 1;
40		return;
41	}
42	find_nearest(value - down, iteration + 1);
43	props[iteration] = -up;
44	if (up - value < 0x100000) {
45		for (i=0; i<=iteration; i++)
46			sols[i] = props[i];
47		solCount = iteration + 1;
48		return;
49	}
50	find_nearest(up - value, iteration + 1);
51}
52
53int
54main()
55{
56	uint64 length = 0xbfee0000; // 0xdfee0000; // 0x9ffb0000; //0xa7f00000; //0x70000000; //0xbfee0000;
57	uint64 base = 0;
58	solCount = 5;
59	find_nearest(length, 0);
60	printf("sols ");
61	int i;
62	for (i=0; i<solCount; i++) {
63		printf("0x%Lx ", sols[i]);
64	}
65	printf("\n");
66
67	bool nextDown = false;
68	for (i = 0; i < solCount; i++) {
69		if (sols[i] < 0) {
70			if (nextDown)
71				base += sols[i];
72			printf("%Lx %Lx %s\n", base, -sols[i], nextDown ? "UC" : "WB");
73			if (!nextDown)
74				base -= sols[i];
75			nextDown = !nextDown;
76		} else {
77			if (nextDown)
78				base -= sols[i];
79			printf("%Lx %Lx %s\n", base, sols[i], nextDown ? "UC" : "WB");
80			if (!nextDown)
81				base += sols[i];
82		}
83
84	}
85}
86