typedef struct { double x, y; } pt;

pt zero(void) { return (pt){ INFINITY, INFINITY }; }


int is_zero(pt p) { return p.x > 1e20 || p.x < -1e20; }

pt neg(pt p) { return (pt){ p.x, -p.y }; }

pt dbl(pt p) {
	if (is_zero(p)) return p;

	pt r;
	double L = (3 * p.x * p.x) / (2 * p.y);
	r.x = L * L - 2 * p.x;
	r.y = L * (p.x - r.x) - p.y;
	return r;
}

pt add(pt p, pt q) {
	if (p.x == q.x && p.y == q.y) return dbl(p);
	if (is_zero(p)) return q;
	if (is_zero(q)) return p;

	pt r;
	double L = (q.y - p.y) / (q.x - p.x);
	r.x = L * L - p.x - q.x;
	r.y = L * (p.x - r.x) - p.y;
	return r;
}

pt mul(pt p, int n) {
	int i;
	pt r = zero();

	for (i = 1; i <= n; i <<= 1) {
		if (i & n) r = add(r, p);
		p = dbl(p);
	}
	return r;
}

void show(const char *s, pt p) {
	printf(, s);
	printf(is_zero(p) ?  : , p.x, p.y);
}

pt from_y(double y) {
	pt r;
	r.x = pow(y * y - C, 1.0/3);
	r.y = y;
	return r;
}

int main(void) {
	pt a, b, c, d;

	a = from_y(1);
	b = from_y(2);

	show(, a);
	show(, b);
	show(, c = add(a, b));
	show(, d = neg(c));
	show(, add(c, d));
	show(, add(a, add(b, d)));
	show(, mul(a, 12345));

	return 0;
}