#include<stdio.h>

/* kbhit() code */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int kbhit() {
  struct timeval tv;
  struct fd_set readfd;

  tv.tv_sec = 0;
  tv.tv_usec = 0;
  FD_ZERO( &readfd );
  FD_SET( 0, &readfd );

  return select( 1, &readfd, NULL, NULL, &tv);
}
/* end kbhit() code */

#define decprec        78
#define b1prec         127
#define b2prec         256   /* b2prec should be b1prec*2+2 */

void main(int argc, char *argv[])
{
int i, j, k, l;
int d[decprec]; 
int b1[b1prec];
int b2[b2prec];
int bn[b2prec][decprec];
int lp1[b2prec];

/* Initializations */
if (argc > 2) {
    printf("Usage: palin [approximate binary startoff]\n");
    exit();
}
printf("\nHit return at any time to stop...\n");
printf("\nInitializing...\n");
l=-1;
for (i=0; i<b1prec; i++) { b1[i]=0; }
for (i=0; i<b2prec; i++) { b2[i]=0; }
/* Initialize bn & lp1 */
bn[0][0]=1; lp1[0]=1;
for (j=1; j<b2prec; j++) { bn[0][j]=0; }
for (i=1; i<b2prec; i++)
{
        k=i-1;
        for (j=0; j<decprec; j++) { bn[i][j]=bn[k][j]*2; }
        /* Now carry digits */
        j=0; while ((bn[i][j]!=0) || (j<lp1[i-1]))
        {
                k=(int)(bn[i][j]/10);
                bn[i][j+1]+=k;
                bn[i][j]=bn[i][j]-k*10;
        j++; }
        lp1[i]=j;
}
if (argc > 1) {
    j=0;
    for (i=strlen(argv[1]); i>=0; i--) {
        if (argv[1][i] == '1') { b1[j]=1; } else { b1[j]=0; }
        j++;
    }
    l=j-1;
}
printf("Ok:\n");


while (!kbhit())     /* Main Loop */
{  
/* Increment b1. */
i=0; while (b1[i]==1) { i++; }
b1[i]=1; 
if (i>l) { l++; }
for (j=0; j<i; j++) { b1[j]=0; }

/* Create b2 binary palindrome #1. */
j=0; for (i=l; i>-1; i-=1) { b2[j]=b1[i]; j++; }
for (i=0; i<=l; i++) { b2[j]=b1[i]; j++; }
         /* j is now the length+1 of b2. (b2[0..j-1]) */

/* Convert b2 to decimal d */
for (i=0; i<decprec; i++) { d[i]=0; }
for (i=0; i<j; i++)
{
        if (b2[i]==1)
        {
                for (k=0; k<lp1[i]; k++)
                { d[k]+=bn[i][k]; }
        }
}
/* Now carry all of the digits to next column. */
i=0; while ((d[i]!=0) || (i<lp1[j-1]))
{
        k=(int)(d[i]/10);
        d[i+1]+=k;
        d[i]=d[i]-k*10;
i++; }    /* i is now the length+1 of d[] */

/* Compare d[] to see if it's a palindrome. If so, printf it. */
k=0;
for (j=0; j<i; j++)
{
        if (d[j]!=d[i-1-j]) k=1;
}
if (k==0) 
{ 
        for (j=(l*2+1); j>-1; j-=1) { printf("%d", b2[j]); }
        i-=1; printf("     ");
        for (j=i; j>-1; j-=1) { printf("%d", d[j]); }
        printf("\n");
}

/* Create b2 binary palindrome #2. */
j=0; for (i=l; i>-1; i-=1) { b2[j]=b1[i]; j++; }
b2[j]=0; j++;
for (i=0; i<=l; i++) { b2[j]=b1[i]; j++; }
         /* j is now the length+1 of b2. (b2[0..j-1]) */

/* Convert b2 to decimal d */
for (i=0; i<decprec; i++) { d[i]=0; }
for (i=0; i<j; i++)
{
        if (b2[i]==1)
        {
                for (k=0; k<lp1[i]; k++)
                { d[k]+=bn[i][k]; }
        }
}
/* Now carry all of the digits to next column. */
i=0; while ((d[i]!=0) || (i<lp1[j-1]))
{
        k=(int)(d[i]/10);
        d[i+1]+=k;
        d[i]=d[i]-k*10;
i++; }    /* i is now the length+1 of d[] */

/* Compare d[] to see if it's a palindrome. If so, printf it. */
k=0;
for (j=0; j<i; j++)
{
        if (d[j]!=d[i-1-j]) k=1;
}
if (k==0) 
{ 
        for (j=(l*2+2); j>-1; j-=1) { printf("%d", b2[j]); }
        i-=1; printf("     ");
        for (j=i; j>-1; j-=1) { printf("%d", d[j]); }
        printf("\n");
}

/* Create b2 binary palindrome #3. */
j=0; for (i=l; i>-1; i-=1) { b2[j]=b1[i]; j++; }
b2[j]=1; j++;
for (i=0; i<=l; i++) { b2[j]=b1[i]; j++; }
         /* j is now the length+1 of b2. (b2[0..j-1]) */

/* Convert b2 to decimal d */
for (i=0; i<decprec; i++) { d[i]=0; }
for (i=0; i<j; i++)
{
        if (b2[i]==1)
        {
                for (k=0; k<lp1[i]; k++)
                { d[k]+=bn[i][k]; }
        }
}
/* Now carry all of the digits to next column. */
i=0; while ((d[i]!=0) || (i<lp1[j-1]))
{
        k=(int)(d[i]/10);
        d[i+1]+=k;
        d[i]=d[i]-k*10;
i++; }    /* i is now the length+1 of d[] */

/* Compare d[] to see if it's a palindrome. If so, printf it. */
k=0;
for (j=0; j<i; j++)
{
        if (d[j]!=d[i-1-j]) k=1;
}
if (k==0) 
{ 
        for (j=(l*2+2); j>-1; j-=1) { printf("%d", b2[j]); }
        i-=1; printf("     ");
        for (j=i; j>-1; j-=1) { printf("%d", d[j]); }
        printf("\n");
}


}       /* End of while (1) loop */
}

