pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:1319:
#endif /* PIKE_DEBUG */ apply_low(o, i, e); args -= e; /* Replace the object with the result. */ assign_svalue(Pike_sp-(args+1), Pike_sp-1); pop_stack(); return args; } }
-
/* Sift down large (absolute) values on the heap. */
-
static void float_heap_sift_down(struct svalue *svalues, int root, int nelems)
-
{
-
FLOAT_ARG_TYPE val = svalues[root].u.float_number;
-
FLOAT_ARG_TYPE abs_val = fabs(val);
-
int child;
-
-
while ((child = ((root<<1) +1)) < nelems) {
-
int swap = root;
-
FLOAT_ARG_TYPE s_abs_val;
-
if ((s_abs_val = fabs(svalues[child].u.float_number)) < abs_val) {
-
swap = child;
-
} else {
-
s_abs_val = abs_val;
-
}
-
child++;
-
if ((child < nelems) &&
-
(fabs(svalues[child].u.float_number) < s_abs_val)) {
-
swap = child;
-
}
-
if (swap == root) break;
-
svalues[root] = svalues[swap];
-
root = swap;
-
}
-
svalues[root].u.float_number = val;
-
}
-
+
/*! @decl mixed `+(mixed arg) *! @decl mixed `+(object arg, mixed ... more) *! @decl int `+(int arg, int ... more) *! @decl float `+(float|int arg, float|int ... more) *! @decl string `+(string|float|int arg, string|float|int ... more) *! @decl array `+(array arg, array ... more) *! @decl mapping `+(mapping arg, mapping ... more) *! @decl multiset `+(multiset arg, multiset ... more) *! *! Addition/concatenation.
pike.git/src/operators.c:1692:
f_add(args); return; } } sp-=args; push_int(size); break; } case BIT_FLOAT:
-
if (args > 2)
{
-
/*
Attempt
to
minimize the accumulated summation error
-
* by adding the smallest (absolute) values first
.
-
*
-
* Large accumulated errors can occur eg when the
number
-
*
of
values to add is of the same order as the largest
-
*
number
representable
by the mantissa alone
.
ie when
-
* the sum differs by an order of magnitude from a
-
* typical term
.
-
*/
-
/* Heapify */
-
for(e
= args
>>
1;
e--;) {
-
float_heap_sift_down(
Pike_sp-
args,
e,
args)
;
+
{
+
double
res
=
Pike_sp[-args]
.
u.float_
number
;
+
for(e=args-1;
e>0;
e--
)
+
res
+=
sp[-e]
.
u
.
float_number;
+
Pike_sp
-
= args
-
1;
+
Pike_sp
[
-
1].u.float_number
=
res
;
}
-
while (args > 2) {
-
/* Pop the smallest element from the heap. */
-
FLOAT_ARG_TYPE top = Pike_sp[-args].u.float_number;
-
Pike_sp[-args] = Pike_sp[-1];
-
Pike_sp--;
-
args--;
-
float_heap_sift_down(Pike_sp-args, 0, args);
-
-
/* And add it to the second smallest. */
-
Pike_sp[-args].u.float_number += top;
-
float_heap_sift_down(Pike_sp-args, 0, args);
-
}
-
}
-
sp[-2].u.float_number += sp[-1].u.float_number;
-
sp--;
+
break; case BIT_FLOAT|BIT_INT: {
-
/*
For
improved
precision
;
partition the values
-
* into floats followed by ints, so that we
-
*
can
add
the
integers exactly.
-
*/
-
int i
=
args
-
1
;
-
e
=
0;
-
while
(e
<
i)
{
-
for
(
;e <
i
; i
-
-) {
-
if
(
TYPEOF(sp[i-args]
)
==
T_FLOAT)
break
;
+
double
res
=
0.0
;
+
for(int
i=0;i<args;i++)
+
if
(TYPEOF(sp[i-args])
==
T_FLOAT)
+
res
+=
Pike_sp[
i
-
args
].u.float_number
;
+
else
+
res
+=
(
double)Pike_sp[
i
-args].u.integer
;
+
Pike_sp-=args;
+
push_float
(
res
)
;
+
return
;
}
-
for(;e < i; e++) {
-
if (TYPEOF(sp[e-args]) == T_INT) break;
-
}
-
if (e < i) {
-
/* Swap */
-
struct svalue sval = sp[e-args];
-
sp[e-args] = sp[i-args];
-
sp[i-args] = sval;
-
}
-
}
-
if (TYPEOF(sp[e-args]) == T_FLOAT) e++;
-
/* Sum the integers. */
-
if (args - e > 1) {
-
f_add(args-e);
-
}
-
args = e+1;
-
o_cast(float_type_string, PIKE_T_FLOAT);
+
-
/* Now all the values should be floats. */
-
goto tail_recurse;
-
}
-
+
#define ADD_WITH_UNDEFINED(TYPE, T_TYPEID, ADD_FUNC, PUSH_FUNC) do { \ int e; \ if (TYPEOF(sp[-args]) == T_INT) { \ if(IS_UNDEFINED(sp-args)) \ { \ struct TYPE *x; \ \ for(e=1;e<args;e++) \ if(TYPEOF(sp[e-args]) != T_TYPEID) \ SIMPLE_ARG_TYPE_ERROR("`+", e+1, #TYPE); \