should be it
This commit is contained in:
360
external/duckdb/extension/tpcds/dsdgen/dsdgen-c/decimal.cpp
vendored
Normal file
360
external/duckdb/extension/tpcds/dsdgen/dsdgen-c/decimal.cpp
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Legal Notice
|
||||
*
|
||||
* This document and associated source code (the "Work") is a part of a
|
||||
* benchmark specification maintained by the TPC.
|
||||
*
|
||||
* The TPC reserves all right, title, and interest to the Work as provided
|
||||
* under U.S. and international laws, including without limitation all patent
|
||||
* and trademark rights therein.
|
||||
*
|
||||
* No Warranty
|
||||
*
|
||||
* 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION
|
||||
* CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE
|
||||
* AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER
|
||||
* WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
|
||||
* INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES,
|
||||
* DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF
|
||||
* WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE.
|
||||
* ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT,
|
||||
* QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT
|
||||
* WITH REGARD TO THE WORK.
|
||||
* 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO
|
||||
* ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE
|
||||
* COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS
|
||||
* OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT,
|
||||
* INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY,
|
||||
* OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT
|
||||
* RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD
|
||||
* ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* Contributors:
|
||||
* Gradient Systems
|
||||
*/
|
||||
|
||||
/*** includes ***/
|
||||
#include "config.h"
|
||||
#include "porting.h"
|
||||
#ifndef USE_STDLIB_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include "decimal.h"
|
||||
#include "mathops.h"
|
||||
|
||||
/*
|
||||
* Routine: set_precision(decimal_t *dest, int size, int precision)
|
||||
* Purpose:
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params:
|
||||
* Returns: None
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
void set_precision(decimal_t *dest, int scale, int precision) {
|
||||
dest->scale = scale;
|
||||
dest->precision = precision;
|
||||
dest->number = 0;
|
||||
dest->flags = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: mk_decimal(int size, int precision)
|
||||
* Purpose: initialize a decimal_t
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params: int size: total number of places in the decimal
|
||||
* int precision: number of places in the fraction
|
||||
* Returns: decimal_t *
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
decimal_t *mk_decimal(int s, int p) {
|
||||
decimal_t *res;
|
||||
|
||||
if ((s < 0) || (p < 0))
|
||||
return (NULL);
|
||||
|
||||
res = (decimal_t *)malloc(sizeof(struct DECIMAL_T));
|
||||
MALLOC_CHECK(res);
|
||||
|
||||
res->flags = 0;
|
||||
res->scale = s;
|
||||
res->precision = p;
|
||||
res->flags |= FL_INIT;
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: itodec(int src, decimal_t *dest)
|
||||
* Purpose: convert an integer to a decimal_t
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params: source integer
|
||||
* Returns: decimal_t *
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO:
|
||||
* 20000104 need to set errno on error
|
||||
*/
|
||||
int itodec(decimal_t *dest, int src) {
|
||||
int scale = 1, bound = 1;
|
||||
|
||||
while ((bound * 10) <= src) {
|
||||
scale += 1;
|
||||
bound *= 10;
|
||||
}
|
||||
|
||||
dest->precision = 0;
|
||||
dest->scale = scale;
|
||||
dest->number = src;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: ftodec(double f, decimal_t *dec)
|
||||
* Purpose: Convert a double to a decimal_t
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params: double f
|
||||
* Returns: decimal_t *
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
int ftodec(decimal_t *dest, double f) {
|
||||
static char valbuf[20];
|
||||
|
||||
sprintf(valbuf, "%f", f);
|
||||
|
||||
return (strtodec(dest, valbuf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: strtodec()
|
||||
* Purpose: Convert an ascii string to a decimal_t structure
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params: char *s
|
||||
* Returns: decimal_t *
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
int strtodec(decimal_t *dest, char *s) {
|
||||
int i;
|
||||
char *d_pt;
|
||||
char valbuf[20];
|
||||
|
||||
strcpy(valbuf, s);
|
||||
dest->flags = 0;
|
||||
if ((d_pt = strchr(valbuf, '.')) == NULL) {
|
||||
dest->scale = strlen(valbuf);
|
||||
dest->number = atoi(valbuf);
|
||||
dest->precision = 0;
|
||||
} else {
|
||||
*d_pt = '\0';
|
||||
d_pt += 1;
|
||||
dest->scale = strlen(valbuf);
|
||||
dest->number = atoi(valbuf);
|
||||
dest->precision = strlen(d_pt);
|
||||
for (i = 0; i < dest->precision; i++)
|
||||
dest->number *= 10;
|
||||
dest->number += atoi(d_pt);
|
||||
}
|
||||
|
||||
if (*s == '-' && dest->number > 0)
|
||||
dest->number *= -1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: dectostr(decimal_t *d, char *buf)
|
||||
* Purpose: convert a decimal structure to a string
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params:
|
||||
* Returns: char *; NULL on success
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
int dectostr(char *dest, decimal_t *d) {
|
||||
ds_key_t number;
|
||||
int i;
|
||||
static char szFormat[20];
|
||||
|
||||
if (!InitConstants::dectostr_init) {
|
||||
sprintf(szFormat, "%s.%s", HUGE_FORMAT, HUGE_FORMAT);
|
||||
InitConstants::dectostr_init = 1;
|
||||
}
|
||||
|
||||
if (d == NULL || dest == NULL)
|
||||
return (-1);
|
||||
for (number = d->number, i = 0; i < d->precision; i++)
|
||||
number /= 10;
|
||||
|
||||
sprintf(dest, szFormat, number, d->number - number);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: dectof(float *dest, decimal_t *d)
|
||||
* Purpose: convert a decimal structure to a double
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params:
|
||||
* Returns: char *; NULL on success
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
int dectoflt(double *dest, decimal_t *d) {
|
||||
if ((dest == NULL) || (d == NULL))
|
||||
return (-1);
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
*dest = d->number;
|
||||
#ifdef _WIN32
|
||||
#pragma warning(default : 4244)
|
||||
#endif
|
||||
while (--d->precision > 0)
|
||||
*dest /= 10.0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine: decimal_t_op(int op, decimal_t *operand1, decimal_t *operand2)
|
||||
* Purpose: execute arbitrary binary operations on decimal_t's
|
||||
* Algorithm:
|
||||
* Data Structures:
|
||||
*
|
||||
* Params:
|
||||
* Returns:
|
||||
* Called By:
|
||||
* Calls:
|
||||
* Assumptions:
|
||||
* Side Effects:
|
||||
* TODO: None
|
||||
*/
|
||||
int decimal_t_op(decimal_t *dest, int op, decimal_t *d1, decimal_t *d2) {
|
||||
int res, np;
|
||||
float f1, f2;
|
||||
|
||||
if ((d1 == NULL) || (d2 == NULL))
|
||||
return (-1);
|
||||
|
||||
dest->scale = (d1->scale > d2->scale) ? d1->scale : d2->scale;
|
||||
if (d1->precision > d2->precision) {
|
||||
dest->precision = d1->precision;
|
||||
} else {
|
||||
dest->precision = d2->precision;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case OP_PLUS:
|
||||
dest->number = d1->number + d2->number;
|
||||
break;
|
||||
case OP_MINUS:
|
||||
dest->number = d1->number - d2->number;
|
||||
break;
|
||||
case OP_MULT:
|
||||
res = d1->precision + d2->precision;
|
||||
dest->number = d1->number * d2->number;
|
||||
while (res-- > dest->precision)
|
||||
dest->number /= 10;
|
||||
break;
|
||||
case OP_DIV:
|
||||
f1 = (float)d1->number;
|
||||
np = d1->precision;
|
||||
while (np < dest->precision) {
|
||||
f1 *= 10.0;
|
||||
np += 1;
|
||||
}
|
||||
np = 0;
|
||||
while (np < dest->precision) {
|
||||
f1 *= 10.0;
|
||||
np += 1;
|
||||
}
|
||||
f2 = (float)d2->number;
|
||||
np = d2->precision;
|
||||
while (np < dest->precision) {
|
||||
f2 *= 10.0;
|
||||
np += 1;
|
||||
}
|
||||
|
||||
dest->number = (int)(f1 / f2);
|
||||
break;
|
||||
default:
|
||||
printf("decimal_t_op does not support op %d\n", op);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
main() {
|
||||
decimal_t *res;
|
||||
int code;
|
||||
|
||||
/* mk_decimal */
|
||||
res = mk_decimal(5, 2);
|
||||
if (res == NULL) {
|
||||
printf("mk_decimal returned NULL\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* itodec */
|
||||
itodec(res, 0);
|
||||
code = dectoi(res);
|
||||
if (code) {
|
||||
printf("r_decimal:itodec(0, res) != 0 (%d)\n", code);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
itodec(res, 999);
|
||||
code = dectoi(res);
|
||||
if (code != 999) {
|
||||
printf("r_decimal:itodec(999, res) != 0 (%d)\n", code);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif /* TEST */
|
||||
Reference in New Issue
Block a user