#include "random.h"
#include "zmult.h"

double randfloat24(void)
{
  uint32 r;

  r = RANDOM;
  r &= 16777215;
  return r - 8388608.0;
}

double randfloat48(void)
{
  uint32 r;
  uint32 s;

  r = RANDOM;
  s = RANDOM;
  return (s * 65536.0 - 140737488355328.0) + r;
}

void printz(double z[],unsigned int n)
{
  if (n == 1) {
    printf("z=%.0f;\n",z[0]);
    return;
  }
  printz(z + n/2,n - n/2);
  printf("z%d=z;\n",n);
  printz(z,n/2);
  printf("z=z+z%d*y^%d;\n",n,n/2);
}

double u[65536];
double v[65536];
double out[65536];
double tmp[65536];

main()
{
  int i;
  int j;

  printf("scale=0;\n");

  zmult_fpmode();

  printf("y=8675309;\n");

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 2;++i) u[i] = randfloat24();
    for (i = 0;i < 2;++i) v[i] = randfloat24();
    printz(u,2); printf("u=z;\n"); printz(v,2); printf("v=z;\n");
    zmult_poly_2(out,u,v,tmp);
    printz(out,3); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 4;++i) u[i] = randfloat24();
    for (i = 0;i < 4;++i) v[i] = randfloat24();
    printz(u,4); printf("u=z;\n"); printz(v,4); printf("v=z;\n");
    zmult_poly_4(out,u,v,tmp);
    printz(out,7); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 16;++i) u[i] = randfloat24();
    for (i = 0;i < 16;++i) v[i] = randfloat24();
    printz(u,16); printf("u=z;\n"); printz(v,16); printf("v=z;\n");
    zmult_poly_16(out,u,v,tmp);
    printz(out,31); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 64;++i) u[i] = randfloat24();
    for (i = 0;i < 64;++i) v[i] = randfloat24();
    printz(u,64); printf("u=z;\n"); printz(v,64); printf("v=z;\n");
    zmult_poly_64(out,u,v,tmp);
    printz(out,127); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 128;++i) u[i] = randfloat24();
    for (i = 0;i < 128;++i) v[i] = randfloat24();
    printz(u,128); printf("u=z;\n"); printz(v,128); printf("v=z;\n");
    zmult_poly_128(out,u,v,tmp);
    printz(out,255); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 256;++i) u[i] = randfloat24();
    for (i = 0;i < 256;++i) v[i] = randfloat24();
    printz(u,256); printf("u=z;\n"); printz(v,256); printf("v=z;\n");
    zmult_poly_256(out,u,v,tmp);
    printz(out,511); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 512;++i) u[i] = randfloat24();
    for (i = 0;i < 512;++i) v[i] = randfloat24();
    printz(u,512); printf("u=z;\n"); printz(v,512); printf("v=z;\n");
    zmult_poly_512(out,u,v,tmp);
    printz(out,1023); printf("u*v-z\n");
  }

  printf("y=2^48;\n");
  
  for (j = 0;j < 10;++j) {
    for (i = 0;i < 4;++i) u[i] = randfloat48();
    for (i = 0;i < 4;++i) v[i] = randfloat48();
    printz(u,4); printf("u=z;\n"); printz(v,4); printf("v=z;\n");
    zmult_48_4_plus(out,u,v,tmp);
    printz(out,4); printf("(u*v-z)%%(2^192+1)\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 32;++i) u[i] = randfloat48();
    for (i = 0;i < 32;++i) v[i] = randfloat48();
    printz(u,32); printf("u=z;\n"); printz(v,32); printf("v=z;\n");
    zmult_48_32_plus(out,u,v,tmp);
    printz(out,32); printf("(u*v-z)%%(2^1536+1)\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 8192;++i) u[i] = randfloat48();
    for (i = 0;i < 8192;++i) v[i] = randfloat48();
    printz(u,8192); printf("u=z;\n"); printz(v,8192); printf("v=z;\n");
    zmult_48_8192_plus(out,u,v,tmp);
    printz(out,8192); printf("(u*v-z)%%(2^393216+1)\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 1;++i) u[i] = randfloat48();
    for (i = 0;i < 1;++i) v[i] = randfloat48();
    printz(u,1); printf("u=z;\n"); printz(v,1); printf("v=z;\n");
    zmult_1(out,u,v,tmp);
    printz(out,2); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 2;++i) u[i] = randfloat48();
    for (i = 0;i < 2;++i) v[i] = randfloat48();
    printz(u,2); printf("u=z;\n"); printz(v,2); printf("v=z;\n");
    zmult_2(out,u,v,tmp);
    printz(out,4); printf("u*v-z\n");
  }

  for (j = 0;j < 10;++j) {
    for (i = 0;i < 4;++i) u[i] = randfloat48();
    for (i = 0;i < 4;++i) v[i] = randfloat48();
    printz(u,4); printf("u=z;\n"); printz(v,4); printf("v=z;\n");
    zmult_4(out,u,v,tmp);
    printz(out,8); printf("u*v-z\n");
  }

  exit(0);
}
