Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion samples/distro-examples/tests/all.bas
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ print "TSAVE:" ':TSAVE file, var
print "VIEW:" ':VIEW [x1,y1,x2,y2 [,color [,border-color]]]
print "WINDOW:" ':WINDOW [x1,y1,x2,y2]
print "WRITE:" ':WRITE #fileN; var1 [, ...]
print "ABS:" + ABS (12.2222)
print "ABS:" + ABS (-12.2222)
print "ABSMAX:" + ABSMAX (1,2,3,4,5,6,7,8,9)
print "ABSMIN:" + ABSMIN (1,2,3,4,5,6,7,8,9)
print "ACOS:" + ACOS (x)
Expand Down Expand Up @@ -217,6 +217,7 @@ print "SQR:" + SQR (x)
print "SQUEEZE:" + SQUEEZE (s)
print "STATMEAN:" + STATMEAN (1,2,3,4,5,6,7,8,9)
print "STATMEANDEV:" + STATMEANDEV (1,2,3,4,5,6,7,8,9)
print "STATMEDIAN:" + STATMEDIAN(1,2,3,4,5,6,7,8,9)
print "STATSPREADP:" + STATSPREADP (1,2,3,4,5,6,7,8,9)
print "STATSPREADS:" + STATSPREADS (1,2,3,4,5,6,7,8,9)
print "STATSTD:" + STATSTD (1,2,3,4,5,6,7,8,9)
Expand Down
3 changes: 2 additions & 1 deletion samples/distro-examples/tests/output/all.out
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ ATANH:nan
ATN:1.489673934694
BCS:catsanddogs
BGETC:
BIN:00000000000000000000000000001100
BIN:1100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add some more testing for BIN. Something like this could be added to strings.bas

bin_test=[[,], [0, "0"], [7, "111"], [14, "1110"], [15, "1111"]]
for t in bin_test
  if (t[1] != bin(t[0])) then throw "err:" + str(t) + " <> " + bin(t[0])
next  

CAT:
CBS:catsanddogs
CEIL:13
Expand Down Expand Up @@ -200,6 +200,7 @@ SQR:3.50713558335004
SQUEEZE:catsanddogs
STATMEAN:5
STATMEANDEV:2.22222222222222
STATMEDIAN:5
STATSPREADP:6.66666666666667
STATSPREADS:7.5
STATSTD:2.73861278752583
Expand Down
8 changes: 8 additions & 0 deletions samples/distro-examples/tests/strings.bas
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,11 @@ REM Only TRIM Strings
if (trim(10) != 10) then throw "err"
if (trim(10.1) != 10.1) then throw "err"
if (trim([1,2,3]) != [1,2,3]) then throw "err"

REM test for integer-to-string conversion
number_test=[[, "0", "0", "0"], [0, "0", "0", "0"], [7, "111", "7", "7"], [14, "1110", "16", "E"], [2090, "100000101010", "4052", "82A"]]
for t in number_test
if (t[1] != bin(t[0])) then throw "err: bin(" + str(t[0]) + ") <> " + t[1]
if (t[2] != oct(t[0])) then throw "err: oct(" + str(t[0]) + ") <> " + t[2]
if (t[3] != hex(t[0])) then throw "err: hex(" + str(t[0]) + ") <> " + t[3]
next
51 changes: 37 additions & 14 deletions src/common/blib_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static char *date_m3_table[] = TABLE_MONTH_3C;
static char *date_mN_table[] = TABLE_MONTH_FULL;

#define BUF_LEN 64
#define BIN_LEN 32 // Number of max bits (digits) kwBIN creates

/*
*/
Expand Down Expand Up @@ -957,19 +958,33 @@ void cmd_str1(long funcCode, var_t *arg, var_t *r) {
//
case kwBIN:
l = v_getint(arg);
IF_ERR_RETURN;
tb = malloc(33);
memset(tb, 0, 33);
for (int i = 0; i < 32; i++) {
IF_ERR_RETURN;

if (l == 0) {
v_createstr(r, "0");
break;
}

tb = malloc(BIN_LEN + 1);
memset(tb, 0, BIN_LEN + 1);

for (int i = 0; i < BIN_LEN; i++) {
if (l & (1 << i)) {
tb[31 - i] = '1';
tb[BIN_LEN - 1 - i] = '1';
} else {
tb[31 - i] = '0';
tb[BIN_LEN - 1 - i] = '0';
}
}

// remove preceding zeros
p = tb;
while (*p == '0') {
p++;
}

r->v.p.ptr = tb;
r->v.p.length = strlen(r->v.p.ptr) + 1;
v_createstr(r, p);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to call free(tb); before the break; line to avoid a memory leak

free(tb);

break;
case kwHEX:
//
Expand Down Expand Up @@ -2307,7 +2322,7 @@ void cmd_genfunc(long funcCode, var_t *r) {
for (int i = 0; i < count - 1; i++) {
r->v.n = r->v.n + (poly[i].x - poly[i + 1].x) * (poly[i].y + poly[i + 1].y);
}
r->v.n = fabs(r->v.n / 2);
r->v.n = r->v.n / 2;

free(poly);
}
Expand All @@ -2327,17 +2342,21 @@ void cmd_genfunc(long funcCode, var_t *r) {
IF_ERR_RETURN;

err = geo_polycentroid(poly, count, &x, &y, &area);
v_toarray1(r, 2);
v_setreal(v_elem(r, 0), x);
v_setreal(v_elem(r, 1), y);

if (err == 1) {
rt_raise(ERR_WRONG_POLY);
}
if (err == 2) {
rt_raise(ERR_CENTROID);
}
// return empty array insead of "rt_raise(ERR_CENTROID);"
v_toarray1(r, 0);
free(poly);
break;
}

v_toarray1(r, 2);
v_setreal(v_elem(r, 0), x);
v_setreal(v_elem(r, 1), y);

free(poly);
}
break;
Expand Down Expand Up @@ -2600,6 +2619,7 @@ void cmd_genfunc(long funcCode, var_t *r) {
//
//
case kwSTATMEANDEV:
case kwSTATMEDIAN:
case kwSTATSTD:
case kwSTATSPREADS:
case kwSTATSPREADP:
Expand Down Expand Up @@ -2670,6 +2690,9 @@ void cmd_genfunc(long funcCode, var_t *r) {
case kwSTATMEANDEV:
r->v.n = statmeandev(dar, tcount);
break;
case kwSTATMEDIAN:
r->v.n = statmedian(dar, tcount);
break;
case kwSTATSTD:
r->v.n = statstd(dar, tcount);
break;
Expand Down
30 changes: 30 additions & 0 deletions src/common/blib_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,36 @@ var_num_t statmeandev(var_num_t *e, int count) {
return sum / count;
}

//
// compare function for median calculation
//
int median_compare(const void * a, const void * b) {
var_num_t fa = *(var_num_t*) a;
var_num_t fb = *(var_num_t*) b;
return (fa > fb) - (fa < fb);
}

//
// Median
//
// Median is calculated using quicksort with a complexity of O(n log n).
// Faster approch would be to implement i.e. quickselect with a
// complexity of O(n).
//
var_num_t statmedian(var_num_t *e, int count) {
if (count == 0) {
return 0;
}

qsort(e, count, sizeof(var_num_t), median_compare);

if (count % 2 == 0) {
return (e[count/2] + e[count/2 - 1]) / 2;
} else {
return e[count/2];
}
}

//
// Standard deviation
//
Expand Down
11 changes: 11 additions & 0 deletions src/common/blib_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ var_num_t mat_determ(var_num_t *a, int n, double toler);
*/
var_num_t statmeandev(var_num_t *e, int count);

/**
* @ingroup math
*
* Median
*
* @param e array with numbers
* @param count number of elements of e
* @return the median
*/
var_num_t statmedian(var_num_t *e, int count);

/**
* @ingroup math
*
Expand Down
1 change: 1 addition & 0 deletions src/common/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,7 @@ static inline void eval_callf(var_t *r) {
case kwSUMSV:
case kwSTATMEAN:
case kwSTATMEANDEV:
case kwSTATMEDIAN:
case kwSTATSTD:
case kwSTATSPREADS:
case kwSTATSPREADP:
Expand Down
1 change: 1 addition & 0 deletions src/common/kw.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ enum func_keywords {
kwSUM,
kwSUMSV,
kwSTATMEAN,
kwSTATMEDIAN,
kwSTATSTD,
kwSTATMEANDEV,
kwSTATSPREADS,
Expand Down
1 change: 1 addition & 0 deletions src/languages/keywords.en.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ struct func_keyword_s func_table[] = {
{ "SUM", kwSUM },
{ "SUMSQ", kwSUMSV },
{ "STATMEAN", kwSTATMEAN },
{ "STATMEDIAN", kwSTATMEDIAN},
{ "STATSTD", kwSTATSTD},
{ "STATMEANDEV", kwSTATMEANDEV },
{ "STATSPREADS", kwSTATSPREADS },
Expand Down