Esempio n. 1
0
int str$$ncompare (	struct dsc$descriptor_s *sd1, 
			struct dsc$descriptor_s *sd2)
{
unsigned short	s1_len,  s2_len;
char		*s1_ptr, *s2_ptr;
int	 	min_len, max_len, i;

	str$$lzerotrim (sd1);
	str$$lzerotrim (sd2);

	str$analyze_sdesc (&*sd1,&s1_len, &s1_ptr);
	str$analyze_sdesc (&*sd2,&s2_len, &s2_ptr);

	min_len = ( s1_len < s2_len) ? s1_len : s2_len;
	max_len = ( s1_len > s2_len) ? s1_len : s2_len;

	if ( s1_len > s2_len )
		return  1;
	if ( s1_len < s2_len )
		return -1;

//	The string are of equal length
	for (i = 0; i < max_len; i++)
	{	if ( s1_ptr[i] > s2_ptr[i] )
			return  1;
		if ( s1_ptr[i] < s2_ptr[i] )
			return -1;
	}

	return 0;
}
Esempio n. 2
0
unsigned long str$mul (const unsigned long *asign,
                       const          long *aexp,
                       const struct dsc$descriptor_s *adigits,
                       const unsigned long *bsign,
                       const          long *bexp,
                       const struct dsc$descriptor_s *bdigits,
                       unsigned       long *csign,
                       long *cexp,
                       struct dsc$descriptor_s *cdigits)
{
    unsigned short	s1_len,  s2_len,  s3_len, temp_len;
    char		*s1_ptr, *s2_ptr, *s3_ptr;
    unsigned long  	index, max_len, min_len;
    int		i,j,k;
    unsigned long	status;
    int		sum,carry;
    char		*a,*b,*c;

    status = STR$_NORMAL;
    index = 0;

    a = (char *) calloc(MAXSTR,1);
    b = (char *) calloc(MAXSTR,1);
    c = (char *) calloc(MAXSTR,1);

    if ( a == NULL )
    {
        status = STR$_INSVIRMEM;
    }
    if ( b == NULL )
    {
        status = STR$_INSVIRMEM;
    }
    if ( c == NULL )
    {
        status = STR$_INSVIRMEM;
    }

//	Check the sign field is 1 or 0
    if ( *asign == 1 || *asign == 0 )
        ;
    else
        status = LIB$_INVARG;

    if ( *bsign == 1  || *bsign == 0)
        ;
    else
        status = LIB$_INVARG;

    if (( *asign == 0 ) && ( *bsign == 0 )) *csign = 0;
    if (( *asign == 0 ) && ( *bsign == 1 )) *csign = 1;
    if (( *asign == 1 ) && ( *bsign == 0 )) *csign = 1;
    if (( *asign == 1 ) && ( *bsign == 1 )) *csign = 0;

//	Get the length of the input strings and how much room for the output
    str$analyze_sdesc (adigits, &s1_len, &s1_ptr);
    str$analyze_sdesc (bdigits, &s2_len, &s2_ptr);
    str$analyze_sdesc (cdigits, &s3_len, &s3_ptr);
    strcpy (s3_ptr,"0");

// 	Quick abort
    if (status != STR$_NORMAL)
    {
        return status;
    }

//	zero out the accumulator
    for (i=0; i < MAXSTR; i++ )
    {
        a[i] = '0';
        b[i] = '0';
        c[i] = 0;
    }

//	Move in the largest number - we need to keep the alignment correct
//	char string is "right to left" alignment
//	start at location specified by the exponent
    max_len = ( s1_len > s2_len ) ? s1_len : s2_len;
    min_len = ( s1_len > s2_len) ? s2_len : s1_len;

//	Copy input strings to working storage
    for (i = 0; i < s1_len; i++ )
    {
        a[i] = s1_ptr[i];
    }
    for (i = 0; i < s2_len; i++ )
    {
        b[i] = s2_ptr[i];
    }

//	Set the output exponent
    *cexp = *aexp + *bexp;

    max_len = s1_len + s2_len;
    sum = 0;
    carry = 0;
    k = max_len;
    for (j = s2_len; j > 0; j--)
    {
        k = max_len - s2_len + j;
        for ( i = s1_len; i > 0; i-- )
        {
            sum = ( b[j-1] - '0' ) * ( a[i-1] - '0');
            sum += carry;
            carry = 0;
            c[k]  += sum % 10;
            if (c[k] > 9 )
            {
                c[k]   -= 10;
                c[k-1] += 1;
            }
            sum   -= sum % 10;
            carry  = sum / 10;
            sum = 0;
            k--;
        }
    }
    c[k] = carry;

//	Truncate output sum string to 65536 MAXUINT16
    if ( max_len > MAXUINT16 )
    {
        status = STR$_TRU;
        max_len = MAXUINT16;
    }

//	Free any memory that is passed into us.
    str$free1_dx (cdigits);
    temp_len = (unsigned short) max_len + 1;
    str$get1_dx(&temp_len, cdigits);
    str$analyze_sdesc (cdigits,&s3_len, &s3_ptr);

    for (i = 0; i <= max_len; i++)
    {
        s3_ptr[i] = (c[i] + '0');
    }

    free (a);
    free (b);
    free (c);

    str$$lzerotrim (cdigits);
    str$$rzerotrim (cdigits,cexp);
    str$$iszerotrim(cdigits,cexp);

    return status;
}
Esempio n. 3
0
unsigned long str$add ( const	unsigned	long *asign,
                        const 			long *aexp,
                        const struct dsc$descriptor_s *adigits,
                        const	unsigned	long *bsign,
                        const 			long *bexp,
                        const struct dsc$descriptor_s *bdigits,
                        unsigned  	long *csign,
                        long *cexp,
                        struct dsc$descriptor_s *cdigits)
{
    unsigned short	s1_len,  s2_len,  s3_len, temp_len;
    char		*s1_ptr, *s2_ptr, *s3_ptr;
    unsigned long  	index,max_len,min_len;
    int		i,j,k;
    unsigned long	status;
    signed long	min_exp,max_exp, a_size, b_size, max_size, min_size;
    char 		ctemp;
    int		sum,carry;
    char		*a,*b,*c;

    status = STR$_NORMAL;
    index = 0;

    a = (char *) calloc(MAXSTR,1);
    b = (char *) calloc(MAXSTR,1);
    c = (char *) calloc(MAXSTR,1);

    if ( a == NULL )
    {
        status = STR$_INSVIRMEM;
    }
    if ( b == NULL )
    {
        status = STR$_INSVIRMEM;
    }
    if ( c == NULL )
    {
        status = STR$_INSVIRMEM;
    }

//	Check the sign field is 1 or 0
    if ( *asign == 1 || *asign == 0 )
        ;
    else
        status = LIB$_INVARG;

    if ( *bsign == 1  || *bsign == 0)
        ;
    else
        status = LIB$_INVARG;

//	If we have a negative sign then call str$subtract
//	c = -a + b
    if (( *asign == 1 ) && (*bsign == 0 ))
    {
        status = str$sub(asign,aexp,adigits,bsign,bexp,bdigits,csign,cexp,cdigits);
        return status;
    }
//	c = a - b
    if (( *asign == 0  ) && (*bsign == 1 ))
    {
        status = str$sub(asign,aexp,adigits,bsign,bexp,bdigits,csign,cexp,cdigits);
        return status;
    }
//	c = -a + -b
    *csign = 0;
    if (( *asign == 1 ) && ( *bsign == 1))
    {
        *csign = 1;
    }

//	Get the length of the input strings and how much room for the output
    str$analyze_sdesc (adigits, &s1_len, &s1_ptr);
    str$analyze_sdesc (bdigits, &s2_len, &s2_ptr);
    str$analyze_sdesc (cdigits, &s3_len, &s3_ptr);
    if ( s3_ptr != NULL )
    {
        str$free1_dx (cdigits);
        printf ("Destination must be NULL\n");
        return STR$_FATINTERR;
    }
// 	Quick abort
    if (status != STR$_NORMAL)
    {
        return status;
    }

//	Move in the largest number - we need to keep the alignment correct
//	char string is "right to left" alignment
//	start at location specified by the exponent
    max_exp = ( *aexp > *bexp ) ? *aexp : *bexp;	// get largest exp
    min_exp = ( *aexp > *bexp ) ? *bexp : *aexp;
    max_len = ( s1_len > s2_len ) ? s1_len : s2_len;
    min_len = ( s1_len > s2_len) ? s2_len : s1_len;
    a_size  = ( *aexp + s1_len );
    b_size  = ( *bexp + s2_len );
    max_size= ( a_size > b_size ) ? a_size : b_size;
    min_size= ( a_size > b_size ) ? b_size : a_size;

// 	The strings don't overlap just return the largest
    if ( max_size - min_size > UINT16_MAX )
    {

//Don't Overlap returning largest
        if ( *aexp > *bexp )
        {
            *cexp = *aexp;
            str$copy_dx (cdigits,adigits);
        }
        else
        {
            *cexp = *bexp;
            str$copy_dx(cdigits,bdigits);
        }
        return STR$_TRU;
    }

//	Copy input strings to working storage
    for (i = 0; i < s1_len; i++ )
    {
        a[i] = s1_ptr[i];
    }
    for (j = 0; j < s2_len; j++ )
    {
        b[j] = s2_ptr[j];
    }

//	Set the output exponent
    *cexp = min_exp;

//	Add zero's to the end of the number for remaining exponent
    if ( *aexp > *bexp )
    {
        for ( i = s1_len; i < s1_len + max_exp - min_exp; i++)
            a[i] = '0';
        s1_len += max_exp - min_exp;
    }
    if ( *aexp < *bexp )
    {
        for ( i = s2_len; i < s2_len + max_exp - min_exp; i++)
            b[i] = '0';
        s2_len += max_exp - min_exp;
    }

    sum = 0;
    carry = 0;
    ctemp = '0';
    i = s1_len;
    j = s2_len;
// 	New max string length
    max_len = ( s1_len > s2_len ) ? s1_len : s2_len ;

    for (k =(int) max_len; k > 0; k-- )
    {
        if ( i > 0 )
        {
            sum += a[i-1] - '0';
        }
        if ( j > 0 )
        {
            sum += b[j-1] - '0';
        }
        sum += carry;
        carry = 0;
        if ( sum > 9 )
        {
            carry = 1;
            sum -= 10;
        }
        ctemp = sum + '0';
        sum = 0;
        c[k-1] = ctemp;
        i--;
        j--;
    }
    if ( carry == 1 )
    {
        for (i = max_len-1; i >= 0; i-- )
        {
            c[i+1] = c[i];
        }
        c[0] = (char) (carry + '0');
        max_len++;
    }


//	Truncate output sum string to 65536 MAXUINT16
    if ( max_len > MAXUINT16 )
    {
        status = STR$_TRU;
        max_len = MAXUINT16;
    }

//	Free any memory that is passed into us.
    temp_len = max_len;
    str$free1_dx(cdigits);

    str$get1_dx(&temp_len,cdigits);
    str$analyze_sdesc (cdigits,&s3_len,&s3_ptr);

    for (i = 0; i < max_len; i++)
    {
        s3_ptr[i] = c[i];
    }

    free (a);
    free (b);
    free (c);
    str$$lzerotrim (&*cdigits);
    str$$rzerotrim (&*cdigits,&*cexp);
    str$$iszerotrim (&*cdigits,&*cexp);

    return status;
}