Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Functions

pgtypes_numeric.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  numeric
struct  decimal

Defines

#define NUMERIC_POS   0x0000
#define NUMERIC_NEG   0x4000
#define NUMERIC_NAN   0xC000
#define NUMERIC_NULL   0xF000
#define NUMERIC_MAX_PRECISION   1000
#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION
#define NUMERIC_MIN_DISPLAY_SCALE   0
#define NUMERIC_MIN_SIG_DIGITS   16
#define DECSIZE   30

Typedefs

typedef unsigned char NumericDigit

Functions

numericPGTYPESnumeric_new (void)
decimalPGTYPESdecimal_new (void)
void PGTYPESnumeric_free (numeric *)
void PGTYPESdecimal_free (decimal *)
numericPGTYPESnumeric_from_asc (char *, char **)
char * PGTYPESnumeric_to_asc (numeric *, int)
int PGTYPESnumeric_add (numeric *, numeric *, numeric *)
int PGTYPESnumeric_sub (numeric *, numeric *, numeric *)
int PGTYPESnumeric_mul (numeric *, numeric *, numeric *)
int PGTYPESnumeric_div (numeric *, numeric *, numeric *)
int PGTYPESnumeric_cmp (numeric *, numeric *)
int PGTYPESnumeric_from_int (signed int, numeric *)
int PGTYPESnumeric_from_long (signed long int, numeric *)
int PGTYPESnumeric_copy (numeric *, numeric *)
int PGTYPESnumeric_from_double (double, numeric *)
int PGTYPESnumeric_to_double (numeric *, double *)
int PGTYPESnumeric_to_int (numeric *, int *)
int PGTYPESnumeric_to_long (numeric *, long *)
int PGTYPESnumeric_to_decimal (numeric *, decimal *)
int PGTYPESnumeric_from_decimal (decimal *, numeric *)

Define Documentation

#define DECSIZE   30

Definition at line 13 of file pgtypes_numeric.h.

Referenced by PGTYPESnumeric_to_decimal().

#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION

Definition at line 9 of file pgtypes_numeric.h.

#define NUMERIC_MAX_PRECISION   1000

Definition at line 8 of file pgtypes_numeric.h.

#define NUMERIC_MIN_DISPLAY_SCALE   0

Definition at line 10 of file pgtypes_numeric.h.

#define NUMERIC_MIN_SIG_DIGITS   16

Definition at line 11 of file pgtypes_numeric.h.

#define NUMERIC_NAN   0xC000

Definition at line 6 of file pgtypes_numeric.h.

#define NUMERIC_NEG   0x4000

Definition at line 5 of file pgtypes_numeric.h.

#define NUMERIC_NULL   0xF000

Definition at line 7 of file pgtypes_numeric.h.

Referenced by ECPGis_noind_null().

#define NUMERIC_POS   0x0000

Definition at line 4 of file pgtypes_numeric.h.


Typedef Documentation

typedef unsigned char NumericDigit

Definition at line 15 of file pgtypes_numeric.h.


Function Documentation

void PGTYPESdecimal_free ( decimal  ) 

Definition at line 473 of file numeric.c.

Referenced by main().

{
    free(var);
}

decimal* PGTYPESdecimal_new ( void   ) 

Definition at line 143 of file numeric.c.

Referenced by main().

{
    decimal    *var;

    if ((var = (decimal *) pgtypes_alloc(sizeof(decimal))) == NULL)
        return NULL;

    memset(var, 0, sizeof(decimal));

    return var;
}

int PGTYPESnumeric_add ( numeric ,
numeric ,
numeric  
)

Definition at line 718 of file numeric.c.

Referenced by decadd(), and main().

{
    /*
     * Decide on the signs of the two variables what to do
     */
    if (var1->sign == NUMERIC_POS)
    {
        if (var2->sign == NUMERIC_POS)
        {
            /*
             * Both are positive result = +(ABS(var1) + ABS(var2))
             */
            if (add_abs(var1, var2, result) != 0)
                return -1;
            result->sign = NUMERIC_POS;
        }
        else
        {
            /*
             * var1 is positive, var2 is negative Must compare absolute values
             */
            switch (cmp_abs(var1, var2))
            {
                case 0:
                    /* ----------
                     * ABS(var1) == ABS(var2)
                     * result = ZERO
                     * ----------
                     */
                    zero_var(result);
                    result->rscale = Max(var1->rscale, var2->rscale);
                    result->dscale = Max(var1->dscale, var2->dscale);
                    break;

                case 1:
                    /* ----------
                     * ABS(var1) > ABS(var2)
                     * result = +(ABS(var1) - ABS(var2))
                     * ----------
                     */
                    if (sub_abs(var1, var2, result) != 0)
                        return -1;
                    result->sign = NUMERIC_POS;
                    break;

                case -1:
                    /* ----------
                     * ABS(var1) < ABS(var2)
                     * result = -(ABS(var2) - ABS(var1))
                     * ----------
                     */
                    if (sub_abs(var2, var1, result) != 0)
                        return -1;
                    result->sign = NUMERIC_NEG;
                    break;
            }
        }
    }
    else
    {
        if (var2->sign == NUMERIC_POS)
        {
            /* ----------
             * var1 is negative, var2 is positive
             * Must compare absolute values
             * ----------
             */
            switch (cmp_abs(var1, var2))
            {
                case 0:
                    /* ----------
                     * ABS(var1) == ABS(var2)
                     * result = ZERO
                     * ----------
                     */
                    zero_var(result);
                    result->rscale = Max(var1->rscale, var2->rscale);
                    result->dscale = Max(var1->dscale, var2->dscale);
                    break;

                case 1:
                    /* ----------
                     * ABS(var1) > ABS(var2)
                     * result = -(ABS(var1) - ABS(var2))
                     * ----------
                     */
                    if (sub_abs(var1, var2, result) != 0)
                        return -1;
                    result->sign = NUMERIC_NEG;
                    break;

                case -1:
                    /* ----------
                     * ABS(var1) < ABS(var2)
                     * result = +(ABS(var2) - ABS(var1))
                     * ----------
                     */
                    if (sub_abs(var2, var1, result) != 0)
                        return -1;
                    result->sign = NUMERIC_POS;
                    break;
            }
        }
        else
        {
            /* ----------
             * Both are negative
             * result = -(ABS(var1) + ABS(var2))
             * ----------
             */
            if (add_abs(var1, var2, result) != 0)
                return -1;
            result->sign = NUMERIC_NEG;
        }
    }

    return 0;
}

int PGTYPESnumeric_cmp ( numeric ,
numeric  
)

Definition at line 1363 of file numeric.c.

Referenced by deccmp(), and main().

{

    /* use cmp_abs function to calculate the result */

    /* both are positive: normal comparation with cmp_abs */
    if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_POS)
        return cmp_abs(var1, var2);

    /* both are negative: return the inverse of the normal comparation */
    if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_NEG)
    {
        /*
         * instead of inverting the result, we invert the paramter ordering
         */
        return cmp_abs(var2, var1);
    }

    /* one is positive, one is negative: trivial */
    if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_NEG)
        return 1;
    if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_POS)
        return -1;

    errno = PGTYPES_NUM_BAD_NUMERIC;
    return INT_MAX;

}

int PGTYPESnumeric_copy ( numeric ,
numeric  
)

Definition at line 1472 of file numeric.c.

Referenced by ecpg_get_data(), ecpg_store_input(), main(), numericvar_to_double(), PGTYPESnumeric_from_double(), and PGTYPESnumeric_to_asc().

{
    int         i;

    if (dst == NULL)
        return -1;
    zero_var(dst);

    dst->weight = src->weight;
    dst->rscale = src->rscale;
    dst->dscale = src->dscale;
    dst->sign = src->sign;

    if (alloc_var(dst, src->ndigits) != 0)
        return -1;

    for (i = 0; i < src->ndigits; i++)
        dst->digits[i] = src->digits[i];

    return 0;
}

int PGTYPESnumeric_div ( numeric ,
numeric ,
numeric  
)

Definition at line 1134 of file numeric.c.

Referenced by decdiv(), and main().

{
    NumericDigit *res_digits;
    int         res_ndigits;
    int         res_sign;
    int         res_weight;
    numeric     dividend;
    numeric     divisor[10];
    int         ndigits_tmp;
    int         weight_tmp;
    int         rscale_tmp;
    int         ri;
    int         i;
    long        guess;
    long        first_have;
    long        first_div;
    int         first_nextdigit;
    int         stat = 0;
    int         rscale;
    int         res_dscale = select_div_scale(var1, var2, &rscale);
    int         err = -1;
    NumericDigit *tmp_buf;

    /*
     * First of all division by zero check
     */
    ndigits_tmp = var2->ndigits + 1;
    if (ndigits_tmp == 1)
    {
        errno = PGTYPES_NUM_DIVIDE_ZERO;
        return -1;
    }

    /*
     * Determine the result sign, weight and number of digits to calculate
     */
    if (var1->sign == var2->sign)
        res_sign = NUMERIC_POS;
    else
        res_sign = NUMERIC_NEG;
    res_weight = var1->weight - var2->weight + 1;
    res_ndigits = rscale + res_weight;
    if (res_ndigits <= 0)
        res_ndigits = 1;

    /*
     * Now result zero check
     */
    if (var1->ndigits == 0)
    {
        zero_var(result);
        result->rscale = rscale;
        return 0;
    }

    /*
     * Initialize local variables
     */
    init_var(&dividend);
    for (i = 1; i < 10; i++)
        init_var(&divisor[i]);

    /*
     * Make a copy of the divisor which has one leading zero digit
     */
    divisor[1].ndigits = ndigits_tmp;
    divisor[1].rscale = var2->ndigits;
    divisor[1].sign = NUMERIC_POS;
    divisor[1].buf = digitbuf_alloc(ndigits_tmp);
    if (divisor[1].buf == NULL)
        goto done;
    divisor[1].digits = divisor[1].buf;
    divisor[1].digits[0] = 0;
    memcpy(&(divisor[1].digits[1]), var2->digits, ndigits_tmp - 1);

    /*
     * Make a copy of the dividend
     */
    dividend.ndigits = var1->ndigits;
    dividend.weight = 0;
    dividend.rscale = var1->ndigits;
    dividend.sign = NUMERIC_POS;
    dividend.buf = digitbuf_alloc(var1->ndigits);
    if (dividend.buf == NULL)
        goto done;
    dividend.digits = dividend.buf;
    memcpy(dividend.digits, var1->digits, var1->ndigits);

    /*
     * Setup the result. Do the allocation in a temporary buffer first, so we
     * don't free result->buf unless we have successfully allocated a buffer
     * to replace it with.
     */
    tmp_buf = digitbuf_alloc(res_ndigits + 2);
    if (tmp_buf == NULL)
        goto done;
    digitbuf_free(result->buf);
    result->buf = tmp_buf;
    res_digits = result->buf;
    result->digits = res_digits;
    result->ndigits = res_ndigits;
    result->weight = res_weight;
    result->rscale = rscale;
    result->sign = res_sign;
    res_digits[0] = 0;

    first_div = divisor[1].digits[1] * 10;
    if (ndigits_tmp > 2)
        first_div += divisor[1].digits[2];

    first_have = 0;
    first_nextdigit = 0;

    weight_tmp = 1;
    rscale_tmp = divisor[1].rscale;

    for (ri = 0; ri <= res_ndigits; ri++)
    {
        first_have = first_have * 10;
        if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits)
            first_have += dividend.digits[first_nextdigit];
        first_nextdigit++;

        guess = (first_have * 10) / first_div + 1;
        if (guess > 9)
            guess = 9;

        while (guess > 0)
        {
            if (divisor[guess].buf == NULL)
            {
                int         i;
                long        sum = 0;

                memcpy(&divisor[guess], &divisor[1], sizeof(numeric));
                divisor[guess].buf = digitbuf_alloc(divisor[guess].ndigits);
                if (divisor[guess].buf == NULL)
                    goto done;
                divisor[guess].digits = divisor[guess].buf;
                for (i = divisor[1].ndigits - 1; i >= 0; i--)
                {
                    sum += divisor[1].digits[i] * guess;
                    divisor[guess].digits[i] = sum % 10;
                    sum /= 10;
                }
            }

            divisor[guess].weight = weight_tmp;
            divisor[guess].rscale = rscale_tmp;

            stat = cmp_abs(&dividend, &divisor[guess]);
            if (stat >= 0)
                break;

            guess--;
        }

        res_digits[ri + 1] = guess;
        if (stat == 0)
        {
            ri++;
            break;
        }

        weight_tmp--;
        rscale_tmp++;

        if (guess == 0)
            continue;

        if (sub_abs(&dividend, &divisor[guess], &dividend) != 0)
            goto done;

        first_nextdigit = dividend.weight - weight_tmp;
        first_have = 0;
        if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits)
            first_have = dividend.digits[first_nextdigit];
        first_nextdigit++;
    }

    result->ndigits = ri + 1;
    if (ri == res_ndigits + 1)
    {
        int         carry = (res_digits[ri] > 4) ? 1 : 0;

        result->ndigits = ri;
        res_digits[ri] = 0;

        while (carry && ri > 0)
        {
            carry += res_digits[--ri];
            res_digits[ri] = carry % 10;
            carry /= 10;
        }
    }

    while (result->ndigits > 0 && *(result->digits) == 0)
    {
        (result->digits)++;
        (result->weight)--;
        (result->ndigits)--;
    }
    while (result->ndigits > 0 && result->digits[result->ndigits - 1] == 0)
        (result->ndigits)--;
    if (result->ndigits == 0)
        result->sign = NUMERIC_POS;

    result->dscale = res_dscale;
    err = 0;                    /* if we've made it this far, return success */

done:

    /*
     * Tidy up
     */
    if (dividend.buf != NULL)
        digitbuf_free(dividend.buf);

    for (i = 1; i < 10; i++)
    {
        if (divisor[i].buf != NULL)
            digitbuf_free(divisor[i].buf);
    }

    return err;
}

void PGTYPESnumeric_free ( numeric  ) 
numeric* PGTYPESnumeric_from_asc ( char *  ,
char **   
)

Definition at line 406 of file numeric.c.

Referenced by deccvasc(), ecpg_get_data(), ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), main(), PGTYPESnumeric_from_double(), and sqlda_common_total_size().

{
    numeric    *value = (numeric *) pgtypes_alloc(sizeof(numeric));
    int         ret;

    char       *realptr;
    char      **ptr = (endptr != NULL) ? endptr : &realptr;

    if (!value)
        return (NULL);

    ret = set_var_from_str(str, ptr, value);
    if (ret)
    {
        PGTYPESnumeric_free(value);
        return (NULL);
    }

    return (value);
}

int PGTYPESnumeric_from_decimal ( decimal ,
numeric  
)

Definition at line 1646 of file numeric.c.

Referenced by deccall2(), deccall3(), dectoasc(), dectodbl(), dectoint(), dectolong(), ecpg_store_input(), and main().

{
    int         i;

    zero_var(dst);

    dst->weight = src->weight;
    dst->rscale = src->rscale;
    dst->dscale = src->dscale;
    dst->sign = src->sign;

    if (alloc_var(dst, src->ndigits) != 0)
        return -1;

    for (i = 0; i < src->ndigits; i++)
        dst->digits[i] = src->digits[i];

    return 0;
}

int PGTYPESnumeric_from_double ( double  ,
numeric  
)

Definition at line 1495 of file numeric.c.

Referenced by deccvdbl().

{
    char        buffer[100];
    numeric    *tmp;
    int         i;

    if (sprintf(buffer, "%f", d) == 0)
        return -1;

    if ((tmp = PGTYPESnumeric_from_asc(buffer, NULL)) == NULL)
        return -1;
    i = PGTYPESnumeric_copy(tmp, dst);
    PGTYPESnumeric_free(tmp);
    if (i != 0)
        return -1;

    errno = 0;
    return 0;
}

int PGTYPESnumeric_from_int ( signed  int,
numeric  
)

Definition at line 1393 of file numeric.c.

Referenced by deccvint(), and main().

{
    /* implicit conversion */
    signed long int long_int = int_val;

    return PGTYPESnumeric_from_long(long_int, var);
}

int PGTYPESnumeric_from_long ( signed long  int,
numeric  
)

Definition at line 1402 of file numeric.c.

Referenced by deccvlong(), main(), and PGTYPESnumeric_from_int().

{
    /* calculate the size of the long int number */
    /* a number n needs log_10 n digits */

    /*
     * however we multiply by 10 each time and compare instead of calculating
     * the logarithm
     */

    int         size = 0;
    int         i;
    signed long int abs_long_val = long_val;
    signed long int extract;
    signed long int reach_limit;

    if (abs_long_val < 0)
    {
        abs_long_val *= -1;
        var->sign = NUMERIC_NEG;
    }
    else
        var->sign = NUMERIC_POS;

    reach_limit = 1;
    do
    {
        size++;
        reach_limit *= 10;
    } while (reach_limit - 1 < abs_long_val && reach_limit <= LONG_MAX / 10);

    if (reach_limit > LONG_MAX / 10)
    {
        /* add the first digit and a .0 */
        size += 2;
    }
    else
    {
        /* always add a .0 */
        size++;
        reach_limit /= 10;
    }

    if (alloc_var(var, size) < 0)
        return -1;

    var->rscale = 1;
    var->dscale = 1;
    var->weight = size - 2;

    i = 0;
    do
    {
        extract = abs_long_val - (abs_long_val % reach_limit);
        var->digits[i] = extract / reach_limit;
        abs_long_val -= extract;
        i++;
        reach_limit /= 10;

        /*
         * we can abandon if abs_long_val reaches 0, because the memory is
         * initialized properly and filled with '0', so converting 10000 in
         * only one step is no problem
         */
    } while (abs_long_val > 0);

    return 0;
}

int PGTYPESnumeric_mul ( numeric ,
numeric ,
numeric  
)

Definition at line 977 of file numeric.c.

Referenced by decmul(), and main().

{
    NumericDigit *res_buf;
    NumericDigit *res_digits;
    int         res_ndigits;
    int         res_weight;
    int         res_sign;
    int         i,
                ri,
                i1,
                i2;
    long        sum = 0;
    int         global_rscale = var1->rscale + var2->rscale;

    res_weight = var1->weight + var2->weight + 2;
    res_ndigits = var1->ndigits + var2->ndigits + 1;
    if (var1->sign == var2->sign)
        res_sign = NUMERIC_POS;
    else
        res_sign = NUMERIC_NEG;

    if ((res_buf = digitbuf_alloc(res_ndigits)) == NULL)
        return -1;
    res_digits = res_buf;
    memset(res_digits, 0, res_ndigits);

    ri = res_ndigits;
    for (i1 = var1->ndigits - 1; i1 >= 0; i1--)
    {
        sum = 0;
        i = --ri;

        for (i2 = var2->ndigits - 1; i2 >= 0; i2--)
        {
            sum += res_digits[i] + var1->digits[i1] * var2->digits[i2];
            res_digits[i--] = sum % 10;
            sum /= 10;
        }
        res_digits[i] = sum;
    }

    i = res_weight + global_rscale + 2;
    if (i >= 0 && i < res_ndigits)
    {
        sum = (res_digits[i] > 4) ? 1 : 0;
        res_ndigits = i;
        i--;
        while (sum)
        {
            sum += res_digits[i];
            res_digits[i--] = sum % 10;
            sum /= 10;
        }
    }

    while (res_ndigits > 0 && *res_digits == 0)
    {
        res_digits++;
        res_weight--;
        res_ndigits--;
    }
    while (res_ndigits > 0 && res_digits[res_ndigits - 1] == 0)
        res_ndigits--;

    if (res_ndigits == 0)
    {
        res_sign = NUMERIC_POS;
        res_weight = 0;
    }

    digitbuf_free(result->buf);
    result->buf = res_buf;
    result->digits = res_digits;
    result->ndigits = res_ndigits;
    result->weight = res_weight;
    result->rscale = global_rscale;
    result->sign = res_sign;
    result->dscale = var1->dscale + var2->dscale;

    return 0;
}

numeric* PGTYPESnumeric_new ( void   ) 

Definition at line 126 of file numeric.c.

Referenced by deccall2(), deccall3(), deccvdbl(), deccvint(), deccvlong(), dectoasc(), dectodbl(), dectoint(), dectolong(), ecpg_get_data(), ecpg_store_input(), main(), numericvar_to_double(), and PGTYPESnumeric_to_asc().

{
    numeric    *var;

    if ((var = (numeric *) pgtypes_alloc(sizeof(numeric))) == NULL)
        return NULL;

    if (alloc_var(var, 0) < 0)
    {
        free(var);
        return NULL;
    }

    return var;
}

int PGTYPESnumeric_sub ( numeric ,
numeric ,
numeric  
)

Definition at line 846 of file numeric.c.

Referenced by decsub(), and main().

{
    /*
     * Decide on the signs of the two variables what to do
     */
    if (var1->sign == NUMERIC_POS)
    {
        if (var2->sign == NUMERIC_NEG)
        {
            /* ----------
             * var1 is positive, var2 is negative
             * result = +(ABS(var1) + ABS(var2))
             * ----------
             */
            if (add_abs(var1, var2, result) != 0)
                return -1;
            result->sign = NUMERIC_POS;
        }
        else
        {
            /* ----------
             * Both are positive
             * Must compare absolute values
             * ----------
             */
            switch (cmp_abs(var1, var2))
            {
                case 0:
                    /* ----------
                     * ABS(var1) == ABS(var2)
                     * result = ZERO
                     * ----------
                     */
                    zero_var(result);
                    result->rscale = Max(var1->rscale, var2->rscale);
                    result->dscale = Max(var1->dscale, var2->dscale);
                    break;

                case 1:
                    /* ----------
                     * ABS(var1) > ABS(var2)
                     * result = +(ABS(var1) - ABS(var2))
                     * ----------
                     */
                    if (sub_abs(var1, var2, result) != 0)
                        return -1;
                    result->sign = NUMERIC_POS;
                    break;

                case -1:
                    /* ----------
                     * ABS(var1) < ABS(var2)
                     * result = -(ABS(var2) - ABS(var1))
                     * ----------
                     */
                    if (sub_abs(var2, var1, result) != 0)
                        return -1;
                    result->sign = NUMERIC_NEG;
                    break;
            }
        }
    }
    else
    {
        if (var2->sign == NUMERIC_NEG)
        {
            /* ----------
             * Both are negative
             * Must compare absolute values
             * ----------
             */
            switch (cmp_abs(var1, var2))
            {
                case 0:
                    /* ----------
                     * ABS(var1) == ABS(var2)
                     * result = ZERO
                     * ----------
                     */
                    zero_var(result);
                    result->rscale = Max(var1->rscale, var2->rscale);
                    result->dscale = Max(var1->dscale, var2->dscale);
                    break;

                case 1:
                    /* ----------
                     * ABS(var1) > ABS(var2)
                     * result = -(ABS(var1) - ABS(var2))
                     * ----------
                     */
                    if (sub_abs(var1, var2, result) != 0)
                        return -1;
                    result->sign = NUMERIC_NEG;
                    break;

                case -1:
                    /* ----------
                     * ABS(var1) < ABS(var2)
                     * result = +(ABS(var2) - ABS(var1))
                     * ----------
                     */
                    if (sub_abs(var2, var1, result) != 0)
                        return -1;
                    result->sign = NUMERIC_POS;
                    break;
            }
        }
        else
        {
            /* ----------
             * var1 is negative, var2 is positive
             * result = -(ABS(var1) + ABS(var2))
             * ----------
             */
            if (add_abs(var1, var2, result) != 0)
                return -1;
            result->sign = NUMERIC_NEG;
        }
    }

    return 0;
}

char* PGTYPESnumeric_to_asc ( numeric ,
int   
)

Definition at line 428 of file numeric.c.

Referenced by dectoasc(), dump_sqlda(), ecpg_store_input(), main(), and PGTYPESnumeric_to_long().

{
    numeric    *numcopy = PGTYPESnumeric_new();
    char       *s;

    if (dscale < 0)
        dscale = num->dscale;

    if (PGTYPESnumeric_copy(num, numcopy) < 0)
    {
        PGTYPESnumeric_free(numcopy);
        return NULL;
    }
    /* get_str_from_var may change its argument */
    s = get_str_from_var(numcopy, dscale);
    PGTYPESnumeric_free(numcopy);
    return (s);
}

int PGTYPESnumeric_to_decimal ( numeric ,
decimal  
)

Definition at line 1623 of file numeric.c.

Referenced by deccall3(), deccvasc(), deccvdbl(), deccvint(), deccvlong(), ecpg_get_data(), and main().

{
    int         i;

    if (src->ndigits > DECSIZE)
    {
        errno = PGTYPES_NUM_OVERFLOW;
        return -1;
    }

    dst->weight = src->weight;
    dst->rscale = src->rscale;
    dst->dscale = src->dscale;
    dst->sign = src->sign;
    dst->ndigits = src->ndigits;

    for (i = 0; i < src->ndigits; i++)
        dst->digits[i] = src->digits[i];

    return 0;
}

int PGTYPESnumeric_to_double ( numeric ,
double *   
)

Definition at line 1564 of file numeric.c.

Referenced by dectodbl(), and main().

{
    double      tmp;

    if (numericvar_to_double(nv, &tmp) != 0)
        return -1;
    *dp = tmp;
    return 0;
}

int PGTYPESnumeric_to_int ( numeric ,
int *   
)

Definition at line 1575 of file numeric.c.

Referenced by dectoint(), and main().

{
    long        l;
    int         i;

    if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
        return i;

    if (l < -INT_MAX || l > INT_MAX)
    {
        errno = PGTYPES_NUM_OVERFLOW;
        return -1;
    }

    *ip = (int) l;
    return 0;
}

int PGTYPESnumeric_to_long ( numeric ,
long *   
)

Definition at line 1594 of file numeric.c.

Referenced by dectolong(), main(), and PGTYPESnumeric_to_int().

{
    char       *s = PGTYPESnumeric_to_asc(nv, 0);
    char       *endptr;

    if (s == NULL)
        return -1;

    errno = 0;
    *lp = strtol(s, &endptr, 10);
    if (endptr == s)
    {
        /* this should not happen actually */
        free(s);
        return -1;
    }
    free(s);
    if (errno == ERANGE)
    {
        if (*lp == LONG_MIN)
            errno = PGTYPES_NUM_UNDERFLOW;
        else
            errno = PGTYPES_NUM_OVERFLOW;
        return -1;
    }
    return 0;
}