#include <iostream>
#include <cassert>
#include <cmath>
double from_storage(unsigned short bits) { //only lowest 10 bits used, upper are ignored
double a = bits&0x1FF;
a /= 5.11967985;
a = a*a;//std::pow(a, 2); // inverse of number in to_storage
return double(bits&0x200 ? -a : a);
}
unsigned short to_storage(double a) { //only lowest 10 bits set/relevant
assert(a<=10000.0);
assert(a>=-10000.0);
if (a >= 0) {
a = std::pow(a, .5); // inverse of number in from_storage
a *= 5.11967985;
unsigned short b = ((unsigned short)(a));
assert((b&0x200)==0);
return b;
} else {
a = std::pow(-a, .5); // inverse of number in from_storage
a *= 5.11967985;
unsigned short b = ((unsigned short)(a));
assert((b&0x200)==0);
return b | 0x200;
}
}
void test(double a) {
unsigned short v = to_storage(a);
double r = from_storage(v);
std::cout << a << '\t' << v << '\t' << r << '\n';
}
int main() {
test(-10000.0);
test( -9950.0);
test( -5000.0);
test( -2500.0);
test( -1000.0);
test( -500.0);
test( -250.0);
test( -100.0);
test( -50.0);
test( -25.0);
for(double d = -10.0; d < 11.5; d += 1)
test(d);
test( 25.0);
test( 50.0);
test( 100.0);
test( 250.0);
test( 500.0);
test( 1000.0);
test( 2500.0);
test( 5000.0);
test( 9950.0);
test(10000.0);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPGNtYXRoPgoKZG91YmxlIGZyb21fc3RvcmFnZSh1bnNpZ25lZCBzaG9ydCBiaXRzKSB7IC8vb25seSBsb3dlc3QgMTAgYml0cyB1c2VkLCB1cHBlciBhcmUgaWdub3JlZAoJZG91YmxlIGEgPSBiaXRzJjB4MUZGOwoJYSAvPSA1LjExOTY3OTg1OwoJYSA9IGEqYTsvL3N0ZDo6cG93KGEsIDIpOyAvLyBpbnZlcnNlIG9mIG51bWJlciBpbiB0b19zdG9yYWdlCglyZXR1cm4gZG91YmxlKGJpdHMmMHgyMDAgPyAtYSA6IGEpOwp9Cgp1bnNpZ25lZCBzaG9ydCB0b19zdG9yYWdlKGRvdWJsZSBhKSB7IC8vb25seSBsb3dlc3QgMTAgYml0cyBzZXQvcmVsZXZhbnQKCWFzc2VydChhPD0xMDAwMC4wKTsKCWFzc2VydChhPj0tMTAwMDAuMCk7CglpZiAoYSA+PSAwKSB7CgkJYSA9IHN0ZDo6cG93KGEsIC41KTsgLy8gaW52ZXJzZSBvZiBudW1iZXIgaW4gZnJvbV9zdG9yYWdlCgkJYSAqPSA1LjExOTY3OTg1OwoJCXVuc2lnbmVkIHNob3J0IGIgPSAoKHVuc2lnbmVkIHNob3J0KShhKSk7CgkJYXNzZXJ0KChiJjB4MjAwKT09MCk7CgkJcmV0dXJuIGI7Cgl9IGVsc2UgewoJCWEgPSBzdGQ6OnBvdygtYSwgLjUpOyAvLyBpbnZlcnNlIG9mIG51bWJlciBpbiBmcm9tX3N0b3JhZ2UKCQlhICo9IDUuMTE5Njc5ODU7CgkJdW5zaWduZWQgc2hvcnQgYiA9ICgodW5zaWduZWQgc2hvcnQpKGEpKTsKCQlhc3NlcnQoKGImMHgyMDApPT0wKTsKCQlyZXR1cm4gYiB8IDB4MjAwOwoJfQp9Cgp2b2lkIHRlc3QoZG91YmxlIGEpIHsKCXVuc2lnbmVkIHNob3J0IHYgPSB0b19zdG9yYWdlKGEpOwoJZG91YmxlIHIgPSBmcm9tX3N0b3JhZ2Uodik7CglzdGQ6OmNvdXQgPDwgYSA8PCAnXHQnIDw8IHYgPDwgJ1x0JyA8PCByIDw8ICdcbic7Cn0KCmludCBtYWluKCkgewoJdGVzdCgtMTAwMDAuMCk7Cgl0ZXN0KCAtOTk1MC4wKTsKCXRlc3QoIC01MDAwLjApOwoJdGVzdCggLTI1MDAuMCk7Cgl0ZXN0KCAtMTAwMC4wKTsKCXRlc3QoICAtNTAwLjApOwoJdGVzdCggIC0yNTAuMCk7Cgl0ZXN0KCAgLTEwMC4wKTsKCXRlc3QoICAgLTUwLjApOwoJdGVzdCggICAtMjUuMCk7Cglmb3IoZG91YmxlIGQgPSAtMTAuMDsgZCA8IDExLjU7IGQgKz0gMSkKCQl0ZXN0KGQpOwoJdGVzdCggICAyNS4wKTsKCXRlc3QoICAgNTAuMCk7Cgl0ZXN0KCAgMTAwLjApOwoJdGVzdCggIDI1MC4wKTsKCXRlc3QoICA1MDAuMCk7Cgl0ZXN0KCAxMDAwLjApOwoJdGVzdCggMjUwMC4wKTsKCXRlc3QoIDUwMDAuMCk7Cgl0ZXN0KCA5OTUwLjApOwoJdGVzdCgxMDAwMC4wKTsKCXJldHVybiAwOwp9