pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:2458:
case 2: o_subtract(); break; default: { INT32 e; TYPE_FIELD types = 0; struct svalue *s=sp-args; for(e=-args;e<0;e++) types|=1<<sp[e].type; if ((types | BIT_INT | BIT_FLOAT) == (BIT_INT | BIT_FLOAT)) {
-
/*
Take
advantage
of
the
precision
control
in
f_add
()
.
*/
+
INT32
carry
=
0;
+
if (types == BIT
_
INT
)
{
f_add(args-1); o_subtract(); break; }
-
+
/* Take advantage of the precision control in f_add(). */
+
for(e = 1; e < args; e++) {
+
if (s[e].type == PIKE_T_INT) {
+
INT_TYPE val = s[e].u.integer;
+
if (val >= -0x7fffffff) {
+
s[e].u.integer = -val;
+
} else {
+
/* Protect against negative overflow. */
+
s[e].u.integer = ~val;
+
carry++;
+
}
+
} else {
+
s[e].u.float_number = -s[e].u.float_number;
+
}
+
}
+
if (carry) {
+
push_int(carry);
+
args++;
+
}
+
f_add(args);
+
break;
+
}
push_svalue(s); for(e=1;e<args;e++) { push_svalue(s+e); o_subtract(); } assign_svalue(s,sp-1); pop_n_elems(sp-s-1); }