MathCache::MathCache() { memset(table, 0, sizeof(table)); /* See comments in lookup(). */ JS_ASSERT(IsNegativeZero(-0.0)); JS_ASSERT(!IsNegativeZero(+0.0)); JS_ASSERT(hash(-0.0, MathCache::Sin) != hash(+0.0, MathCache::Sin)); }
double js::ecmaAtan2(double y, double x) { #if defined(_MSC_VER) /* * MSVC's atan2 does not yield the result demanded by ECMA when both x * and y are infinite. * - The result is a multiple of pi/4. * - The sign of y determines the sign of the result. * - The sign of x determines the multiplicator, 1 or 3. */ if (IsInfinite(y) && IsInfinite(x)) { double z = js_copysign(M_PI / 4, y); if (x < 0) z *= 3; return z; } #endif #if defined(SOLARIS) && defined(__GNUC__) if (y == 0) { if (IsNegativeZero(x)) return js_copysign(M_PI, y); if (x == 0) return y; } #endif return atan2(y, x); }
static double min_double(double x, double y) { // Math.min(num, NaN) => NaN, Math.min(-0, +0) => -0 if (x < y || IsNaN(x) || (x == y && IsNegativeZero(x))) return x; return y; }
double js::math_min_impl(double x, double y) { // Math.min(num, NaN) => NaN, Math.min(-0, +0) => -0 if (x < y || IsNaN(x) || (x == y && IsNegativeZero(x))) return x; return y; }
double js::math_sin_uncached(double x) { #ifdef _WIN64 // Workaround MSVC bug where sin(-0) is +0 instead of -0 on x64 on // CPUs without FMA3 (pre-Haswell). See bug 1076670. if (IsNegativeZero(x)) return -0.0; #endif return sin(x); }
static bool RenderDouble(WasmRenderContext& c, double num) { if (IsNegativeZero(num)) return c.buffer.append("-0"); if (IsNaN(num)) return c.buffer.append("nan"); if (IsInfinite(num)) { if (num > 0) return c.buffer.append("infinity"); return c.buffer.append("-infinity"); } return NumberValueToStringBuffer(c.cx, DoubleValue(num), c.buffer); }
static bool RenderDouble(WasmRenderContext& c, double d) { if (IsNaN(d)) return RenderNaN(c.sb(), d); if (IsNegativeZero(d)) return c.buffer.append("-0"); if (IsInfinite(d)) { if (d > 0) return c.buffer.append("infinity"); return c.buffer.append("-infinity"); } return NumberValueToStringBuffer(c.cx, DoubleValue(d), c.sb()); }
bool js_math_min(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); double minval = PositiveInfinity<double>(); for (unsigned i = 0; i < args.length(); i++) { double x; if (!ToNumber(cx, args[i], &x)) return false; // Math.min(num, NaN) => NaN, Math.min(-0, +0) => -0 if (x < minval || IsNaN(x) || (x == minval && IsNegativeZero(x))) minval = x; } args.rval().setNumber(minval); return true; }
static void TestPredicates() { MOZ_ASSERT(IsNaN(UnspecifiedNaN())); MOZ_ASSERT(IsNaN(SpecificNaN(1, 17)));; MOZ_ASSERT(IsNaN(SpecificNaN(0, 0xfffffffffff0fULL))); MOZ_ASSERT(!IsNaN(0)); MOZ_ASSERT(!IsNaN(-0.0)); MOZ_ASSERT(!IsNaN(1.0)); MOZ_ASSERT(!IsNaN(PositiveInfinity())); MOZ_ASSERT(!IsNaN(NegativeInfinity())); MOZ_ASSERT(IsInfinite(PositiveInfinity())); MOZ_ASSERT(IsInfinite(NegativeInfinity())); MOZ_ASSERT(!IsInfinite(UnspecifiedNaN())); MOZ_ASSERT(!IsInfinite(0)); MOZ_ASSERT(!IsInfinite(-0.0)); MOZ_ASSERT(!IsInfinite(1.0)); MOZ_ASSERT(!IsFinite(PositiveInfinity())); MOZ_ASSERT(!IsFinite(NegativeInfinity())); MOZ_ASSERT(!IsFinite(UnspecifiedNaN())); MOZ_ASSERT(IsFinite(0)); MOZ_ASSERT(IsFinite(-0.0)); MOZ_ASSERT(IsFinite(1.0)); MOZ_ASSERT(!IsNegative(PositiveInfinity())); MOZ_ASSERT(IsNegative(NegativeInfinity())); MOZ_ASSERT(IsNegative(-0.0)); MOZ_ASSERT(!IsNegative(0.0)); MOZ_ASSERT(IsNegative(-1.0)); MOZ_ASSERT(!IsNegative(1.0)); MOZ_ASSERT(!IsNegativeZero(PositiveInfinity())); MOZ_ASSERT(!IsNegativeZero(NegativeInfinity())); MOZ_ASSERT(!IsNegativeZero(SpecificNaN(1, 17)));; MOZ_ASSERT(!IsNegativeZero(SpecificNaN(1, 0xfffffffffff0fULL))); MOZ_ASSERT(!IsNegativeZero(SpecificNaN(0, 17)));; MOZ_ASSERT(!IsNegativeZero(SpecificNaN(0, 0xfffffffffff0fULL))); MOZ_ASSERT(!IsNegativeZero(UnspecifiedNaN())); MOZ_ASSERT(IsNegativeZero(-0.0)); MOZ_ASSERT(!IsNegativeZero(0.0)); MOZ_ASSERT(!IsNegativeZero(-1.0)); MOZ_ASSERT(!IsNegativeZero(1.0)); int32_t i; MOZ_ASSERT(DoubleIsInt32(0.0, &i)); MOZ_ASSERT(i == 0); MOZ_ASSERT(!DoubleIsInt32(-0.0, &i)); MOZ_ASSERT(DoubleEqualsInt32(0.0, &i)); MOZ_ASSERT(i == 0); MOZ_ASSERT(DoubleEqualsInt32(-0.0, &i)); MOZ_ASSERT(i == 0); MOZ_ASSERT(DoubleIsInt32(INT32_MIN, &i)); MOZ_ASSERT(i == INT32_MIN); MOZ_ASSERT(DoubleIsInt32(INT32_MAX, &i)); MOZ_ASSERT(i == INT32_MAX); MOZ_ASSERT(DoubleEqualsInt32(INT32_MIN, &i)); MOZ_ASSERT(i == INT32_MIN); MOZ_ASSERT(DoubleEqualsInt32(INT32_MAX, &i)); MOZ_ASSERT(i == INT32_MAX); MOZ_ASSERT(!DoubleIsInt32(0.5, &i)); MOZ_ASSERT(!DoubleIsInt32(double(INT32_MAX) + 0.1, &i)); MOZ_ASSERT(!DoubleIsInt32(double(INT32_MIN) - 0.1, &i)); MOZ_ASSERT(!DoubleIsInt32(NegativeInfinity(), &i)); MOZ_ASSERT(!DoubleIsInt32(PositiveInfinity(), &i)); MOZ_ASSERT(!DoubleIsInt32(UnspecifiedNaN(), &i)); MOZ_ASSERT(!DoubleEqualsInt32(0.5, &i)); MOZ_ASSERT(!DoubleEqualsInt32(double(INT32_MAX) + 0.1, &i)); MOZ_ASSERT(!DoubleEqualsInt32(double(INT32_MIN) - 0.1, &i)); MOZ_ASSERT(!DoubleEqualsInt32(NegativeInfinity(), &i)); MOZ_ASSERT(!DoubleEqualsInt32(PositiveInfinity(), &i)); MOZ_ASSERT(!DoubleEqualsInt32(UnspecifiedNaN(), &i)); }