/*******************************************************************

                 Les Fonctions Flottantes en C
                 utilisable sur tous les UNIX.

 *****************************************************************
   Ce fichier est en lecture seule hors du projet ALE de l'INRIA  
 Il est maintenu par : ILOG S.A. 9 rue Royale, 75008 Paris, France
 *****************************************************************

$Header: llfloat.c,v 4.4 88/11/22 15:29:33 kuczynsk Exp $

 *******************************************************************/

/*
  Les conditionnelles de compilation
  
  IBMRT   : l'IBM RT
  SUN4    : les SUN 4
  SUNOS40 : Les syste`mes UN*X  SUN OS 4.0

*/

#include <signal.h>
#include <errno.h>
#include <math.h>

extern int errno;

/* Les accus flottants simples pre'cisions, obligatoires pour forcer le
   compilateur C a traiter la simple pre'cision (les parame`tres flottants
   sont toujours traite's en double pre'cision!).
   Il sont de'clare's dans <systeme>/ll<systeme>.llm3.               */
extern float accusingle1;
extern float accusingle2;


/********************/
/*  Les Conversions */
/********************/

/* Conversions flottants <--> ascii */

extern char *gcvt();

/* Conversion double flottant -> ascii */

int cvftoa(number, buffer) double number; char *buffer; {
char* depart;
int point;
	point = 0;
	depart = gcvt(number, 12, buffer);
	while(*buffer != '\0')
	     if(*buffer++ == '.')
	       point = 1;
	if(point == 0){
	  *buffer++ = '.';
	  *buffer = '\0';
	}
	return(buffer - depart);
}

/* Conversion simple flottant ->  ascii */

int cvstoa( buffer) char *buffer; {
char* depart;
int point;
	point = 0;
#ifdef IBMRT
        depart = buffer;
        sprintf(buffer,"%g",accusingle1);
#else
        depart = gcvt(accusingle1, 7, buffer);
#endif /* IBMRT */
	while(*buffer != '\0')
	     if(*buffer++ == '.')
	       point = 1;
	if(point == 0){
	  *buffer++ = '.';
	  *buffer = '\0';
	}
	return(buffer - depart);
}

extern double atof();

/* Conversion ascii -> double flottant */

double cvatof (buffer)
char *buffer;
{
	double foo;

	errno = 0;
	foo = atof(buffer);
/* the sun4 and SunOS4.0 have IEEE routines which routine Inf. */
#ifndef SUN4
#ifndef SUNOS40
	if (errno == ERANGE)
		kill (getpid(), SIGFPE);
#endif SUNOS40
#endif SUN4
	return(foo);
}

/* Conversion ascii -> simple flottant */

cvatos (buffer)
char *buffer;
{
	double foo;

	errno = 0;
	foo = atof(buffer);
/* the sun4 and SunOS4.0 have IEEE routines which routine Inf. */
#ifndef SUN4
#ifndef SUNOS40
	if (errno == ERANGE)
		kill (getpid(), SIGFPE);
#endif
#endif
	accusingle2=foo;
#ifdef UNIGRAPH
	asm("fmov.s accusingle2,%fp0");
#endif UNIGRAPH
}

/* Conversions doubles flottants <--> fixnums */

double floatc (n) int n;{
       return(n);
}

int fixc(f) double f;{
    return(f);
}

/* Convertions  simples flottants <--> fixnums */

sfloatc (n) int n; {
       accusingle2=n;
}

int sfixc() {
    return (accusingle1);
}

/* Conversions  simples flottants <--> doubles flottants */

dtosc (f) double f; {
      accusingle2=f;
}

double stodc () {
       return (accusingle1);
}

/***********************************/
/* Arithmetique doubles flottants  */
/* operations elementaires doubles */
/***********************************/

double fplus(f1, f2) double f1, f2; {
	return(f2 + f1);
}

double fdiff(f1, f2) double f1, f2; {
	return(f2 - f1);
}

double ftimes(f1, f2) double f1, f2; {
	return(f2 * f1);
}

double fquo(f1, f2) double f1, f2; {
	return(f2 / f1);
}

int cfbeq (f1, f2) double f1, f2; {
	return(f1 == f2);
}

int cfbne (f1, f2) double f1, f2; {
	return(f1 != f2);
}

int cfble (f1, f2) double f1, f2; {
	return(f1 <= f2);
}

int cfblt (f1, f2) double f1, f2; {
	return(f1 < f2);
}

int cfbge (f1, f2) double f1, f2; {
	return(f1 >= f2);
}

int cfbgt (f1, f2) double f1, f2; {
	return(f1 > f2);
}

/* Les fonctions circulaires et mathematiques doubles */

double fsin(f1) double f1; {
	return(sin(f1));
}

double fcos(f1) double f1; {
	return(cos(f1));
}

double fasin(f1) double f1; {
	return(asin(f1));
}

double facos(f1) double f1; {
	return(acos(f1));
}

double fatan(f1) double f1; {
	return(atan(f1));
}

double fexp(f1) double f1; {
	return(exp(f1));
}

double flog(f1) double f1; {
	return(log(f1));
}

double flog10(f1) double f1; {
	return(log10(f1));
}

double fpower(f1,f2) double f1, f2; {
	return(pow(f1,f2));
}

double fsqrt(f1) double f1; {
	return(sqrt(f1));
}

/********************************************/
/* Arithmetique simples flottants           */
/* operations elementaires simple precision */
/********************************************/

/* sens   accu2 op acc1 -> accu2 */

splus() {
	accusingle2=accusingle2+accusingle1;
}

sdiff() {
	accusingle2=accusingle2-accusingle1;
}


stimes() {
	accusingle2=accusingle2*accusingle1;
}

squo() {
	accusingle2=accusingle2/accusingle1;
}

int csbeq () {
	return(accusingle1 == accusingle2);
}

int csbne () {
	return(accusingle1 != accusingle2);
}

int csble () {
	return(accusingle1 <= accusingle2);
}

int csblt () {
	return(accusingle1 < accusingle2);
}

int csbge () {
	return(accusingle1 >= accusingle2);
}

int csbgt () {
	return(accusingle1 > accusingle2);
}


/* Les fonctions circulaires et mathematiques simple presicion */

ssin() {
	accusingle2=sin(accusingle1);
}

scos() {
	accusingle2=cos(accusingle1);
}

sasin() {
	accusingle2=asin(accusingle1);
}

sacos() {
	accusingle2=acos(accusingle1);
}

satan() {
	accusingle2=atan(accusingle1);
}

sexp() {
	accusingle2=exp(accusingle1);
}

slog() {
	accusingle2=log(accusingle1);
}

slog10() {
	accusingle2=log10(accusingle1);
}

spower() {
	accusingle2=pow(accusingle1,accusingle2);
}

ssqrt() {
	accusingle2=sqrt(accusingle1);
}