Skip to content

Commit 7b2d0a8

Browse files
authored
Merge pull request #173 from Joe7M/master
Bug fix for BIN and changes to return values of POLYCENT and POLYAREA
2 parents eefca91 + 4e66025 commit 7b2d0a8

File tree

9 files changed

+93
-16
lines changed

9 files changed

+93
-16
lines changed

samples/distro-examples/tests/all.bas

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ print "TSAVE:" ':TSAVE file, var
9999
print "VIEW:" ':VIEW [x1,y1,x2,y2 [,color [,border-color]]]
100100
print "WINDOW:" ':WINDOW [x1,y1,x2,y2]
101101
print "WRITE:" ':WRITE #fileN; var1 [, ...]
102-
print "ABS:" + ABS (12.2222)
102+
print "ABS:" + ABS (-12.2222)
103103
print "ABSMAX:" + ABSMAX (1,2,3,4,5,6,7,8,9)
104104
print "ABSMIN:" + ABSMIN (1,2,3,4,5,6,7,8,9)
105105
print "ACOS:" + ACOS (x)
@@ -217,6 +217,7 @@ print "SQR:" + SQR (x)
217217
print "SQUEEZE:" + SQUEEZE (s)
218218
print "STATMEAN:" + STATMEAN (1,2,3,4,5,6,7,8,9)
219219
print "STATMEANDEV:" + STATMEANDEV (1,2,3,4,5,6,7,8,9)
220+
print "STATMEDIAN:" + STATMEDIAN(1,2,3,4,5,6,7,8,9)
220221
print "STATSPREADP:" + STATSPREADP (1,2,3,4,5,6,7,8,9)
221222
print "STATSPREADS:" + STATSPREADS (1,2,3,4,5,6,7,8,9)
222223
print "STATSTD:" + STATSTD (1,2,3,4,5,6,7,8,9)

samples/distro-examples/tests/output/all.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ ATANH:nan
103103
ATN:1.489673934694
104104
BCS:catsanddogs
105105
BGETC:
106-
BIN:00000000000000000000000000001100
106+
BIN:1100
107107
CAT:
108108
CBS:catsanddogs
109109
CEIL:13
@@ -200,6 +200,7 @@ SQR:3.50713558335004
200200
SQUEEZE:catsanddogs
201201
STATMEAN:5
202202
STATMEANDEV:2.22222222222222
203+
STATMEDIAN:5
203204
STATSPREADP:6.66666666666667
204205
STATSPREADS:7.5
205206
STATSTD:2.73861278752583

samples/distro-examples/tests/strings.bas

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,11 @@ REM Only TRIM Strings
202202
if (trim(10) != 10) then throw "err"
203203
if (trim(10.1) != 10.1) then throw "err"
204204
if (trim([1,2,3]) != [1,2,3]) then throw "err"
205+
206+
REM test for integer-to-string conversion
207+
number_test=[[, "0", "0", "0"], [0, "0", "0", "0"], [7, "111", "7", "7"], [14, "1110", "16", "E"], [2090, "100000101010", "4052", "82A"]]
208+
for t in number_test
209+
if (t[1] != bin(t[0])) then throw "err: bin(" + str(t[0]) + ") <> " + t[1]
210+
if (t[2] != oct(t[0])) then throw "err: oct(" + str(t[0]) + ") <> " + t[2]
211+
if (t[3] != hex(t[0])) then throw "err: hex(" + str(t[0]) + ") <> " + t[3]
212+
next

src/common/blib_func.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ static char *date_m3_table[] = TABLE_MONTH_3C;
3131
static char *date_mN_table[] = TABLE_MONTH_FULL;
3232

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

3536
/*
3637
*/
@@ -957,19 +958,33 @@ void cmd_str1(long funcCode, var_t *arg, var_t *r) {
957958
//
958959
case kwBIN:
959960
l = v_getint(arg);
960-
IF_ERR_RETURN;
961-
tb = malloc(33);
962-
memset(tb, 0, 33);
963-
for (int i = 0; i < 32; i++) {
961+
IF_ERR_RETURN;
962+
963+
if (l == 0) {
964+
v_createstr(r, "0");
965+
break;
966+
}
967+
968+
tb = malloc(BIN_LEN + 1);
969+
memset(tb, 0, BIN_LEN + 1);
970+
971+
for (int i = 0; i < BIN_LEN; i++) {
964972
if (l & (1 << i)) {
965-
tb[31 - i] = '1';
973+
tb[BIN_LEN - 1 - i] = '1';
966974
} else {
967-
tb[31 - i] = '0';
975+
tb[BIN_LEN - 1 - i] = '0';
968976
}
969977
}
978+
979+
// remove preceding zeros
980+
p = tb;
981+
while (*p == '0') {
982+
p++;
983+
}
970984

971-
r->v.p.ptr = tb;
972-
r->v.p.length = strlen(r->v.p.ptr) + 1;
985+
v_createstr(r, p);
986+
free(tb);
987+
973988
break;
974989
case kwHEX:
975990
//
@@ -2307,7 +2322,7 @@ void cmd_genfunc(long funcCode, var_t *r) {
23072322
for (int i = 0; i < count - 1; i++) {
23082323
r->v.n = r->v.n + (poly[i].x - poly[i + 1].x) * (poly[i].y + poly[i + 1].y);
23092324
}
2310-
r->v.n = fabs(r->v.n / 2);
2325+
r->v.n = r->v.n / 2;
23112326

23122327
free(poly);
23132328
}
@@ -2327,17 +2342,21 @@ void cmd_genfunc(long funcCode, var_t *r) {
23272342
IF_ERR_RETURN;
23282343

23292344
err = geo_polycentroid(poly, count, &x, &y, &area);
2330-
v_toarray1(r, 2);
2331-
v_setreal(v_elem(r, 0), x);
2332-
v_setreal(v_elem(r, 1), y);
23332345

23342346
if (err == 1) {
23352347
rt_raise(ERR_WRONG_POLY);
23362348
}
23372349
if (err == 2) {
2338-
rt_raise(ERR_CENTROID);
2339-
}
2350+
// return empty array insead of "rt_raise(ERR_CENTROID);"
2351+
v_toarray1(r, 0);
2352+
free(poly);
2353+
break;
2354+
}
23402355

2356+
v_toarray1(r, 2);
2357+
v_setreal(v_elem(r, 0), x);
2358+
v_setreal(v_elem(r, 1), y);
2359+
23412360
free(poly);
23422361
}
23432362
break;
@@ -2600,6 +2619,7 @@ void cmd_genfunc(long funcCode, var_t *r) {
26002619
//
26012620
//
26022621
case kwSTATMEANDEV:
2622+
case kwSTATMEDIAN:
26032623
case kwSTATSTD:
26042624
case kwSTATSPREADS:
26052625
case kwSTATSPREADP:
@@ -2670,6 +2690,9 @@ void cmd_genfunc(long funcCode, var_t *r) {
26702690
case kwSTATMEANDEV:
26712691
r->v.n = statmeandev(dar, tcount);
26722692
break;
2693+
case kwSTATMEDIAN:
2694+
r->v.n = statmedian(dar, tcount);
2695+
break;
26732696
case kwSTATSTD:
26742697
r->v.n = statstd(dar, tcount);
26752698
break;

src/common/blib_math.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,36 @@ var_num_t statmeandev(var_num_t *e, int count) {
232232
return sum / count;
233233
}
234234

235+
//
236+
// compare function for median calculation
237+
//
238+
int median_compare(const void * a, const void * b) {
239+
var_num_t fa = *(var_num_t*) a;
240+
var_num_t fb = *(var_num_t*) b;
241+
return (fa > fb) - (fa < fb);
242+
}
243+
244+
//
245+
// Median
246+
//
247+
// Median is calculated using quicksort with a complexity of O(n log n).
248+
// Faster approch would be to implement i.e. quickselect with a
249+
// complexity of O(n).
250+
//
251+
var_num_t statmedian(var_num_t *e, int count) {
252+
if (count == 0) {
253+
return 0;
254+
}
255+
256+
qsort(e, count, sizeof(var_num_t), median_compare);
257+
258+
if (count % 2 == 0) {
259+
return (e[count/2] + e[count/2 - 1]) / 2;
260+
} else {
261+
return e[count/2];
262+
}
263+
}
264+
235265
//
236266
// Standard deviation
237267
//

src/common/blib_math.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ var_num_t mat_determ(var_num_t *a, int n, double toler);
7575
*/
7676
var_num_t statmeandev(var_num_t *e, int count);
7777

78+
/**
79+
* @ingroup math
80+
*
81+
* Median
82+
*
83+
* @param e array with numbers
84+
* @param count number of elements of e
85+
* @return the median
86+
*/
87+
var_num_t statmedian(var_num_t *e, int count);
88+
7889
/**
7990
* @ingroup math
8091
*

src/common/eval.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ static inline void eval_callf(var_t *r) {
11751175
case kwSUMSV:
11761176
case kwSTATMEAN:
11771177
case kwSTATMEANDEV:
1178+
case kwSTATMEDIAN:
11781179
case kwSTATSTD:
11791180
case kwSTATSPREADS:
11801181
case kwSTATSPREADP:

src/common/kw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ enum func_keywords {
348348
kwSUM,
349349
kwSUMSV,
350350
kwSTATMEAN,
351+
kwSTATMEDIAN,
351352
kwSTATSTD,
352353
kwSTATMEANDEV,
353354
kwSTATSPREADS,

src/languages/keywords.en.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ struct func_keyword_s func_table[] = {
288288
{ "SUM", kwSUM },
289289
{ "SUMSQ", kwSUMSV },
290290
{ "STATMEAN", kwSTATMEAN },
291+
{ "STATMEDIAN", kwSTATMEDIAN},
291292
{ "STATSTD", kwSTATSTD},
292293
{ "STATMEANDEV", kwSTATMEANDEV },
293294
{ "STATSPREADS", kwSTATSPREADS },

0 commit comments

Comments
 (0)