Re: Converting to and from FAC

From: Steve Judd (sjudd_at_ffd2.com)
Date: 2000-10-19 19:14:35

Hola Spirio, all,

Thanks for the code, Spirio.  Since I just can't stand being outdone
(actually because I got curious) I attempted to write a conversion
routine.  Actually I wrote two; one is fast, the other is maybe a little
more compact.  Maybe someone can improve on them?  I tested them on 10,
-0.5, and sqrt(2).

Hope someone finds this useful!

-S

First the fast one, which converts the number to base 256 and then shifts
left as necessary (since the float can go from 2^-128 to 2^126, it can
basically go from 256^-16 to 256^16):

---

/*
 * num2float.c
 *
 * Convert number to C64 floating-point format.
 *
 * SLJ 10/19/00
 */

#include <stdio.h>

int main(int argc, char** argv[])
{
    int i,sign;
    unsigned long c1,c2,offset,ei;
    unsigned char digit[33];

    double num=1.4142135624,a;

    if (num == 0) printf("Oh come on.  Zero! 00 00 00 00 00\n");

    printf("Original number = %f\n",num);
    if (num < 0) {
	sign=128; 
	num = -num;
    } else sign=0;

    a = 1;
    for (i=0; i<16; i++) {		/* a = 256^16 */
	a = a*256;
    }

    ei=32;				/* convert to base 256 */
    for (i=0; i<33; i++) {
	if (num >= a) {
	    digit[i] = num/a;
	    num = num - a*digit[i];
	    if (i < ei) ei = i;		/* first nonzero byte */
	} else digit[i] = 0;
	a = a/256;
    }

    offset = 0;
    while (digit[ei] < 128 && 
	   digit[ei] != 0) {		/* Shift left to get first 1 */
	offset++;
	c1=0;
	for (i=32; i>=ei; i--) {
	    if (digit[i] < 128) c2=0; else c2=1;
	    digit[i] = digit[i]*2 + c1;
	    c1 = c2;
	}
    }
    digit[ei] = (digit[ei]-128) | sign;

    printf("C64 float = %d %d %d %d %d\n",129 + 8*(16-ei)+7 - offset,
		digit[ei],digit[ei+1],digit[ei+2],digit[ei+3]);
}

---

The "slow" one just does a straight binary conversion:

---

/*
 * num2float.c
 *
 * Convert number to C64 floating-point format -- slow but compact.
 *
 * SLJ 10/19/00
 */

#include <stdio.h>

int main(int argc, char** argv[])
{
    int i,sign,bit,byte,flag,count,ei;
    unsigned char digit[5];

    double num=1.4142135624,a;

    if (num == 0) printf("Oh come on.  Zero! 00 00 00 00 00\n");

    printf("Original number = %f\n",num);
    if (num < 0) {
	sign=128; 
	num = -num;
    } else sign=0;

    a = 1;
    for (i=0; i<126; i++) {		/* a = 2^126 */
	a = a*2;
    }

    byte=0;
    flag=0;
    count=0;

    for (i=126; i>=-128 && byte<4; i--) {
	if (num >= a) {
	    bit=1;
	    if (flag == 0) ei = i;
	    flag=1;
	} else bit=0;
	if (flag == 1) {
	    digit[byte] = digit[byte]*2 + bit;
	    count++;
	    if (count > 7) {
		count = 0;
		byte++;
	    }
	    num = num - a*bit;
	}
	a = a/2;
    }

    digit[0] = (digit[0]-128) | sign;

    printf("C64 float = %d %d %d %d %d\n",129 + ei,
		digit[0],digit[1],digit[2],digit[3]);
}


-
This message was sent through the cbm-hackers mailing list.
To unsubscribe: echo unsubscribe | mail cbm-hackers-request@dot.tml.hut.fi.

Archive generated by hypermail 2.1.1.