#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <inttypes.h>
#include <endian.h>
#include <vector>
typedef unsigned int uint_t;
typedef long double real;
template<typename T> class Adder
{
std::vector<T> v;
public:
void clear() {
v.clear();
v.push_back(0);
}
Adder() {
clear();
}
void add(T x) {
size_t i = 0;
for (i = 0; v[i]; i++) {
x += v[i];
v[i] = 0;
}
v[i] = x;
if (i + 1 == v.size())
v.push_back(0);
}
T value() {
T res = v[0];
size_t l = v.size();
for (size_t i = 1; i < l; i++)
res += v[i];
return res;
}
};
static void work(uint64_t n0, uint64_t n1)
{
assert (n0 < n1);
assert ((n1 - n0) % 2 != 0);
Adder<real> s;
uint64_t buf[2];
for (uint64_t i = n0; i <= n1; i += 2) {
size_t cnt = fread(buf, sizeof(buf[0]), 2, stdin);
assert (cnt == 2);
buf[0] = be64toh(buf[0]);
buf[1] = be64toh(buf[1]);
// fprintf(stderr, "p0=%" PRIu64 ", p1=%" PRIu64 "\n", buf[0], buf[1]);
real p0 = buf[0], p1 = buf[1];
real d = (p0 - (p1 - p0) * i) / (p0 * p1);
s.add(d);
}
printf("%.24Lf\n", s.value());
}
int main(int ac, char **av)
{
uint64_t as[2] = {0, 0};
assert (ac == 3);
for (uint_t i = 0; i < 2; i++) {
char *eptr = 0;
as[i] = strtoull(av[1 + i], &eptr, 0);
if (as[i] == 0 || eptr == av[1 + i] || eptr == 0 || *eptr != 0) {
fprintf(stderr, "wrong argument %u: '%s' \n", i, av[1 + i]);
}
fprintf(stderr, "as[%u] = %" PRIu64 " \n", i, as[i]);
}
assert (as[0] < as[1]);
assert ((as[1] - as[0]) % 2 != 0);
work(as[0], as[1]);
return 0;
}
Comments