abs returned a negative absolute valueWhat happened. abs applied to the most negative integer returned that integer, sign and all.
(printout t "abs: " (abs -9223372036854775808) crlf)
printed
abs: -9223372036854775808
Why it is a fix and not a preference. Section 12.5.8 of the Basic Programming Guide says the function "returns the absolute value of its only argument", and that "the return value will either be integer or float (depending upon the type the argument)". An absolute value is not negative. Section 2.3.1 says an optional sign followed by digits is stored as an integer and that CLIPS represents an integer as a C long long, so −9223372036854775808 is a value a program can write and the scanner will store: ScanNumber passes the numeral to strtoll, which accepts it, and errno stays 0.
The one integer with no answer here is the one whose negation leaves the type, and the same directory already treats that as an evaluation error: DivFunction in bmathfun.c on LLONG_MIN / -1, ModFunction in emathfun.c on the same pair. Both report through ArgumentOverUnderflowErrorMessage, "Over or underflow of long long integer".
Where it came from. AbsFunction in bmathfun.c negated without a test:
if (CVIsType(returnValue,INTEGER_BIT))
{
long long lv = returnValue->integerValue->contents;
if (lv < 0L)
{ returnValue->integerValue = CreateInteger(theEnv,-lv); }
}
-lv on LLONG_MIN has no result in long long. On this host it yields LLONG_MIN back, so the branch ran, created an integer, and returned the argument.
The change. AbsFunction tests for LLONG_MIN before the negation and, on that value, reports through ArgumentOverUnderflowErrorMessage, sets the evaluation error, and returns — the shape DivFunction uses in the same file. The float branch is left alone; no double has a negation outside double.
What was checked. (abs -9223372036854775808) reports and prints no value; −9223372036854775808 appears nowhere in what abs produced; a call after it still evaluates. div, mod and abs on their respective arguments all report through PRNTUTIL17, so the three agree. Then the arguments that answer: both examples the guide gives, (abs -2) and (abs 4.0); −9223372036854775807, the integer next to the reported one, which is still negated; the largest positive integer; zero; and the largest magnitude double, which the float branch still negates.
The reason to care about this one: the wrong answer arrived as a plain value with no diagnostic, and the sign of a result from abs is the last thing a reader checks.
Present in 7.0? Not checked.
Anonymous