зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset a30cf37ddcab (bug 1447668) for build bustages at /builds/worker/workspace/build/src/js/src/ctypes/CTypes.cpp:2607 on a CLOSED TREE
--HG-- rename : js/src/jsapi-tests/testToSignedOrUnsignedInteger.cpp => js/src/jsapi-tests/testToIntWidth.cpp
This commit is contained in:
Родитель
08cf6c4ee3
Коммит
eb84122ef9
|
@ -286,25 +286,27 @@ ToObject(JSContext* cx, HandleValue v)
|
|||
return js::ToObjectSlow(cx, v, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a double value to UnsignedInteger (an unsigned integral type) using
|
||||
namespace detail {
|
||||
|
||||
/*
|
||||
* Convert a double value to ResultType (an unsigned integral type) using
|
||||
* ECMAScript-style semantics (that is, in like manner to how ECMAScript's
|
||||
* ToInt32 converts to int32_t).
|
||||
*
|
||||
* If d is infinite or NaN, return 0.
|
||||
* Otherwise compute d2 = sign(d) * floor(abs(d)), and return the
|
||||
* UnsignedInteger value congruent to d2 % 2**(bit width of UnsignedInteger).
|
||||
* Otherwise compute d2 = sign(d) * floor(abs(d)), and return the ResultType
|
||||
* value congruent to d2 mod 2**(bit width of ResultType).
|
||||
*
|
||||
* The algorithm below is inspired by that found in
|
||||
* <https://trac.webkit.org/changeset/67825/webkit/trunk/JavaScriptCore/runtime/JSValue.cpp>
|
||||
* <http://trac.webkit.org/changeset/67825/trunk/JavaScriptCore/runtime/JSValue.cpp>
|
||||
* but has been generalized to all integer widths.
|
||||
*/
|
||||
template<typename UnsignedInteger>
|
||||
inline UnsignedInteger
|
||||
ToUnsignedInteger(double d)
|
||||
template<typename ResultType>
|
||||
inline ResultType
|
||||
ToUintWidth(double d)
|
||||
{
|
||||
static_assert(mozilla::IsUnsigned<UnsignedInteger>::value,
|
||||
"UnsignedInteger must be an unsigned type");
|
||||
static_assert(mozilla::IsUnsigned<ResultType>::value,
|
||||
"ResultType must be an unsigned type");
|
||||
|
||||
uint64_t bits = mozilla::BitwiseCast<uint64_t>(d);
|
||||
unsigned DoubleExponentShift = mozilla::FloatingPoint<double>::kExponentShift;
|
||||
|
@ -323,23 +325,23 @@ ToUnsignedInteger(double d)
|
|||
uint_fast16_t exponent = mozilla::AssertedCast<uint_fast16_t>(exp);
|
||||
|
||||
// If the exponent is greater than or equal to the bits of precision of a
|
||||
// double plus UnsignedInteger's width, the number is either infinite, NaN,
|
||||
// or too large to have lower-order bits in the congruent value. (Example:
|
||||
// double plus ResultType's width, the number is either infinite, NaN, or
|
||||
// too large to have lower-order bits in the congruent value. (Example:
|
||||
// 2**84 is exactly representable as a double. The next exact double is
|
||||
// 2**84 + 2**32. Thus if UnsignedInteger is uint32_t, an exponent >= 84
|
||||
// implies floor(abs(d)) == 0 mod 2**32.) Return 0 in all these cases.
|
||||
constexpr size_t ResultWidth = CHAR_BIT * sizeof(UnsignedInteger);
|
||||
// 2**84 + 2**32. Thus if ResultType is int32_t, an exponent >= 84 implies
|
||||
// floor(abs(d)) == 0 mod 2**32.) Return 0 in all these cases.
|
||||
const size_t ResultWidth = CHAR_BIT * sizeof(ResultType);
|
||||
if (exponent >= DoubleExponentShift + ResultWidth)
|
||||
return 0;
|
||||
|
||||
// The significand contains the bits that will determine the final result.
|
||||
// Shift those bits left or right, according to the exponent, to their
|
||||
// locations in the unsigned binary representation of floor(abs(d)).
|
||||
static_assert(sizeof(UnsignedInteger) <= sizeof(uint64_t),
|
||||
"left-shifting below would lose upper bits");
|
||||
UnsignedInteger result = (exponent > DoubleExponentShift)
|
||||
? UnsignedInteger(bits << (exponent - DoubleExponentShift))
|
||||
: UnsignedInteger(bits >> (DoubleExponentShift - exponent));
|
||||
static_assert(sizeof(ResultType) <= sizeof(uint64_t),
|
||||
"Left-shifting below would lose upper bits");
|
||||
ResultType result = (exponent > DoubleExponentShift)
|
||||
? ResultType(bits << (exponent - DoubleExponentShift))
|
||||
: ResultType(bits >> (DoubleExponentShift - exponent));
|
||||
|
||||
// Two further complications remain. First, |result| may contain bogus
|
||||
// sign/exponent bits. Second, IEEE-754 numbers' significands (excluding
|
||||
|
@ -366,7 +368,7 @@ ToUnsignedInteger(double d)
|
|||
// The implicit leading bit matters identically to the other case, so
|
||||
// again, |exponent < ResultWidth|.
|
||||
if (exponent < ResultWidth) {
|
||||
UnsignedInteger implicitOne = UnsignedInteger(1) << exponent;
|
||||
ResultType implicitOne = ResultType(1) << exponent;
|
||||
result &= implicitOne - 1; // remove bogus bits
|
||||
result += implicitOne; // add the implicit bit
|
||||
}
|
||||
|
@ -375,27 +377,28 @@ ToUnsignedInteger(double d)
|
|||
return (bits & mozilla::FloatingPoint<double>::kSignBit) ? ~result + 1 : result;
|
||||
}
|
||||
|
||||
template<typename SignedInteger>
|
||||
inline SignedInteger
|
||||
ToSignedInteger(double d)
|
||||
template<typename ResultType>
|
||||
inline ResultType
|
||||
ToIntWidth(double d)
|
||||
{
|
||||
static_assert(mozilla::IsSigned<SignedInteger>::value,
|
||||
"SignedInteger must be a signed type");
|
||||
static_assert(mozilla::IsSigned<ResultType>::value,
|
||||
"ResultType must be a signed type");
|
||||
|
||||
using UnsignedInteger = typename mozilla::MakeUnsigned<SignedInteger>::Type;
|
||||
UnsignedInteger u = ToUnsignedInteger<UnsignedInteger>(d);
|
||||
using UnsignedResult = typename mozilla::MakeUnsigned<ResultType>::Type;
|
||||
UnsignedResult u = ToUintWidth<UnsignedResult>(d);
|
||||
|
||||
return mozilla::WrapToSigned(u);
|
||||
}
|
||||
|
||||
// clang crashes compiling this when targeting arm:
|
||||
// https://llvm.org/bugs/show_bug.cgi?id=22974
|
||||
#if defined (__arm__) && defined (__GNUC__) && !defined(__clang__)
|
||||
} // namespace detail
|
||||
|
||||
template<>
|
||||
/* ES5 9.5 ToInt32 (specialized for doubles). */
|
||||
inline int32_t
|
||||
ToSignedInteger<int32_t>(double d)
|
||||
ToInt32(double d)
|
||||
{
|
||||
// clang crashes compiling this when targeting arm:
|
||||
// https://llvm.org/bugs/show_bug.cgi?id=22974
|
||||
#if defined (__arm__) && defined (__GNUC__) && !defined(__clang__)
|
||||
int32_t i;
|
||||
uint32_t tmp0;
|
||||
uint32_t tmp1;
|
||||
|
@ -516,94 +519,57 @@ ToSignedInteger<int32_t>(double d)
|
|||
: "cc"
|
||||
);
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif // defined (__arm__) && defined (__GNUC__) && !defined(__clang__)
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename IntegerType,
|
||||
bool IsUnsigned = mozilla::IsUnsigned<IntegerType>::value>
|
||||
struct ToSignedOrUnsignedInteger;
|
||||
|
||||
template<typename IntegerType>
|
||||
struct ToSignedOrUnsignedInteger<IntegerType, true>
|
||||
{
|
||||
static IntegerType compute(double d) {
|
||||
return ToUnsignedInteger<IntegerType>(d);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename IntegerType>
|
||||
struct ToSignedOrUnsignedInteger<IntegerType, false>
|
||||
{
|
||||
static IntegerType compute(double d) {
|
||||
return ToSignedInteger<IntegerType>(d);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename IntegerType>
|
||||
inline IntegerType
|
||||
ToSignedOrUnsignedInteger(double d)
|
||||
{
|
||||
return detail::ToSignedOrUnsignedInteger<IntegerType>::compute(d);
|
||||
}
|
||||
|
||||
/* WEBIDL 4.2.4 */
|
||||
inline int8_t
|
||||
ToInt8(double d)
|
||||
{
|
||||
return ToSignedInteger<int8_t>(d);
|
||||
}
|
||||
|
||||
/* ECMA-262 7.1.10 ToUInt8() specialized for doubles. */
|
||||
inline int8_t
|
||||
ToUint8(double d)
|
||||
{
|
||||
return ToUnsignedInteger<uint8_t>(d);
|
||||
}
|
||||
|
||||
/* WEBIDL 4.2.6 */
|
||||
inline int16_t
|
||||
ToInt16(double d)
|
||||
{
|
||||
return ToSignedInteger<int16_t>(d);
|
||||
}
|
||||
|
||||
inline uint16_t
|
||||
ToUint16(double d)
|
||||
{
|
||||
return ToUnsignedInteger<uint16_t>(d);
|
||||
}
|
||||
|
||||
/* ES5 9.5 ToInt32 (specialized for doubles). */
|
||||
inline int32_t
|
||||
ToInt32(double d)
|
||||
{
|
||||
return ToSignedInteger<int32_t>(d);
|
||||
#else
|
||||
return detail::ToIntWidth<int32_t>(d);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ES5 9.6 (specialized for doubles). */
|
||||
inline uint32_t
|
||||
ToUint32(double d)
|
||||
{
|
||||
return ToUnsignedInteger<uint32_t>(d);
|
||||
return detail::ToUintWidth<uint32_t>(d);
|
||||
}
|
||||
|
||||
/* WEBIDL 4.2.4 */
|
||||
inline int8_t
|
||||
ToInt8(double d)
|
||||
{
|
||||
return detail::ToIntWidth<int8_t>(d);
|
||||
}
|
||||
|
||||
/* ECMA-262 7.1.10 ToUInt8() specialized for doubles. */
|
||||
inline int8_t
|
||||
ToUint8(double d)
|
||||
{
|
||||
return detail::ToUintWidth<uint8_t>(d);
|
||||
}
|
||||
|
||||
/* WEBIDL 4.2.6 */
|
||||
inline int16_t
|
||||
ToInt16(double d)
|
||||
{
|
||||
return detail::ToIntWidth<int16_t>(d);
|
||||
}
|
||||
|
||||
inline uint16_t
|
||||
ToUint16(double d)
|
||||
{
|
||||
return detail::ToUintWidth<uint16_t>(d);
|
||||
}
|
||||
|
||||
/* WEBIDL 4.2.10 */
|
||||
inline int64_t
|
||||
ToInt64(double d)
|
||||
{
|
||||
return ToSignedInteger<int64_t>(d);
|
||||
return detail::ToIntWidth<int64_t>(d);
|
||||
}
|
||||
|
||||
/* WEBIDL 4.2.11 */
|
||||
inline uint64_t
|
||||
ToUint64(double d)
|
||||
{
|
||||
return ToUnsignedInteger<uint64_t>(d);
|
||||
return detail::ToUintWidth<uint64_t>(d);
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
|
|
@ -11,24 +11,22 @@
|
|||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/TextUtils.h"
|
||||
#include "mozilla/Vector.h"
|
||||
#include "mozilla/WrappingOperations.h"
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#if defined(XP_WIN)
|
||||
# include <float.h>
|
||||
#endif
|
||||
#if defined(SOLARIS)
|
||||
# include <ieeefp.h>
|
||||
#endif
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#ifdef HAVE_SSIZE_T
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <type_traits>
|
||||
#if defined(XP_UNIX)
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "jsexn.h"
|
||||
#include "jsnum.h"
|
||||
|
@ -2582,52 +2580,54 @@ JS_STATIC_ASSERT(sizeof(float) == 4);
|
|||
JS_STATIC_ASSERT(sizeof(PRFuncPtr) == sizeof(void*));
|
||||
JS_STATIC_ASSERT(numeric_limits<double>::is_signed);
|
||||
|
||||
template<typename TargetType,
|
||||
typename FromType,
|
||||
bool FromIsIntegral = std::is_integral<FromType>::value>
|
||||
struct ConvertImpl;
|
||||
|
||||
template<typename TargetType, typename FromType>
|
||||
struct ConvertImpl<TargetType, FromType, false>
|
||||
{
|
||||
static MOZ_ALWAYS_INLINE TargetType Convert(FromType input) {
|
||||
return JS::ToSignedOrUnsignedInteger<TargetType>(input);
|
||||
// Templated helper to convert FromType to TargetType, for the default case
|
||||
// where the trivial POD constructor will do.
|
||||
template<class TargetType, class FromType>
|
||||
struct ConvertImpl {
|
||||
static MOZ_ALWAYS_INLINE TargetType Convert(FromType d) {
|
||||
return TargetType(d);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TargetType>
|
||||
inline TargetType
|
||||
ConvertUnsignedTargetTo(typename std::make_unsigned<TargetType>::type input)
|
||||
{
|
||||
return std::is_signed<TargetType>::value ? mozilla::WrapToSigned(input) : input;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
// MSVC can't perform double to unsigned __int64 conversion when the
|
||||
// double is greater than 2^63 - 1. Help it along a little.
|
||||
template<>
|
||||
struct ConvertImpl<uint64_t, double> {
|
||||
static MOZ_ALWAYS_INLINE uint64_t Convert(double d) {
|
||||
return d > 0x7fffffffffffffffui64 ?
|
||||
uint64_t(d - 0x8000000000000000ui64) + 0x8000000000000000ui64 :
|
||||
uint64_t(d);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// C++ doesn't guarantee that exact values are the only ones that will
|
||||
// round-trip. In fact, on some platforms, including SPARC, there are pairs of
|
||||
// values, a uint64_t and a double, such that neither value is exactly
|
||||
// representable in the other type, but they cast to each other.
|
||||
#if defined(SPARC) || defined(__powerpc__)
|
||||
// Simulate x86 overflow behavior
|
||||
template<>
|
||||
struct ConvertImpl<uint64_t, double> {
|
||||
static MOZ_ALWAYS_INLINE uint64_t Convert(double d) {
|
||||
return d >= 0xffffffffffffffff ?
|
||||
0x8000000000000000 : uint64_t(d);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline char16_t
|
||||
ConvertUnsignedTargetTo<char16_t>(char16_t input)
|
||||
{
|
||||
// mozilla::WrapToSigned can't be used on char16_t.
|
||||
return input;
|
||||
}
|
||||
|
||||
template<typename TargetType, typename FromType>
|
||||
struct ConvertImpl<TargetType, FromType, true>
|
||||
{
|
||||
static MOZ_ALWAYS_INLINE TargetType Convert(FromType input) {
|
||||
using UnsignedTargetType = typename std::make_unsigned<TargetType>::type;
|
||||
auto resultUnsigned = static_cast<UnsignedTargetType>(input);
|
||||
|
||||
return ConvertUnsignedTargetTo<TargetType>(resultUnsigned);
|
||||
struct ConvertImpl<int64_t, double> {
|
||||
static MOZ_ALWAYS_INLINE int64_t Convert(double d) {
|
||||
return d >= 0x7fffffffffffffff ?
|
||||
0x8000000000000000 : int64_t(d);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class TargetType, class FromType>
|
||||
static MOZ_ALWAYS_INLINE TargetType Convert(FromType d)
|
||||
{
|
||||
static_assert(std::is_integral<FromType>::value !=
|
||||
std::is_floating_point<FromType>::value,
|
||||
"should only be converting from floating/integral type");
|
||||
|
||||
return ConvertImpl<TargetType, FromType>::Convert(d);
|
||||
}
|
||||
|
||||
|
@ -2690,8 +2690,8 @@ struct IsExactImpl<TargetType, FromType, true, false> {
|
|||
template<class TargetType, class FromType>
|
||||
static MOZ_ALWAYS_INLINE bool ConvertExact(FromType i, TargetType* result)
|
||||
{
|
||||
static_assert(std::numeric_limits<TargetType>::is_exact,
|
||||
"TargetType must be exact to simplify conversion");
|
||||
// Require that TargetType is integral, to simplify conversion.
|
||||
JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
|
||||
|
||||
*result = Convert<TargetType>(i);
|
||||
|
||||
|
@ -3106,11 +3106,9 @@ jsvalToIntegerExplicit(HandleValue val, IntegerType* result)
|
|||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
|
||||
if (val.isDouble()) {
|
||||
// Convert using ToInt32-style semantics: non-finite numbers become 0, and
|
||||
// everything else rounds toward zero then maps into |IntegerType| with
|
||||
// wraparound semantics.
|
||||
// Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
|
||||
double d = val.toDouble();
|
||||
*result = JS::ToSignedOrUnsignedInteger<IntegerType>(d);
|
||||
*result = mozilla::IsFinite(d) ? IntegerType(d) : 0;
|
||||
return true;
|
||||
}
|
||||
if (val.isObject()) {
|
||||
|
|
|
@ -99,7 +99,7 @@ UNIFIED_SOURCES += [
|
|||
'testThreadingExclusiveData.cpp',
|
||||
'testThreadingMutex.cpp',
|
||||
'testThreadingThread.cpp',
|
||||
'testToSignedOrUnsignedInteger.cpp',
|
||||
'testToIntWidth.cpp',
|
||||
'testTypedArrays.cpp',
|
||||
'testUbiNode.cpp',
|
||||
'testUncaughtSymbol.cpp',
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "js/Conversions.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using JS::detail::ToIntWidth;
|
||||
using JS::detail::ToUintWidth;
|
||||
|
||||
BEGIN_TEST(testToUint8TwiceUint8Range)
|
||||
{
|
||||
double d = -256;
|
||||
uint8_t expected = 0;
|
||||
do {
|
||||
CHECK(ToUintWidth<uint8_t>(d) == expected);
|
||||
|
||||
d++;
|
||||
expected++;
|
||||
} while (d <= 256);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToUint8TwiceUint8Range)
|
||||
|
||||
BEGIN_TEST(testToInt8)
|
||||
{
|
||||
double d = -128;
|
||||
int8_t expected = -128;
|
||||
do {
|
||||
CHECK(ToIntWidth<int8_t>(d) == expected);
|
||||
|
||||
d++;
|
||||
expected++;
|
||||
} while (expected < 127);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToInt8)
|
||||
|
||||
BEGIN_TEST(testToUint32Large)
|
||||
{
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 83)) == 0);
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 83) + pow(2.0, 31)) == (1U << 31));
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 83) + 2 * pow(2.0, 31)) == 0);
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 83) + 3 * pow(2.0, 31)) == (1U << 31));
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 84)) == 0);
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 84) + pow(2.0, 31)) == 0);
|
||||
CHECK(ToUintWidth<uint32_t>(pow(2.0, 84) + pow(2.0, 32)) == 0);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToUint32Large)
|
||||
|
||||
BEGIN_TEST(testToUint64Large)
|
||||
{
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 115)) == 0);
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 115) + pow(2.0, 63)) == (1ULL << 63));
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 115) + 2 * pow(2.0, 63)) == 0);
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 115) + 3 * pow(2.0, 63)) == (1ULL << 63));
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 116)) == 0);
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 116) + pow(2.0, 63)) == 0);
|
||||
CHECK(ToUintWidth<uint64_t>(pow(2.0, 116) + pow(2.0, 64)) == 0);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToUint64Large)
|
|
@ -1,69 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "js/Conversions.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using JS::ToSignedInteger;
|
||||
using JS::ToUnsignedInteger;
|
||||
|
||||
BEGIN_TEST(testToUint8TwiceUint8Range)
|
||||
{
|
||||
double d = -256;
|
||||
uint8_t expected = 0;
|
||||
do {
|
||||
CHECK(ToUnsignedInteger<uint8_t>(d) == expected);
|
||||
|
||||
d++;
|
||||
expected++;
|
||||
} while (d <= 256);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToUint8TwiceUint8Range)
|
||||
|
||||
BEGIN_TEST(testToInt8)
|
||||
{
|
||||
double d = -128;
|
||||
int8_t expected = -128;
|
||||
do {
|
||||
CHECK(ToSignedInteger<int8_t>(d) == expected);
|
||||
|
||||
d++;
|
||||
expected++;
|
||||
} while (expected < 127);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToInt8)
|
||||
|
||||
BEGIN_TEST(testToUint32Large)
|
||||
{
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 83)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 83) + pow(2.0, 31)) == (1U << 31));
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 83) + 2 * pow(2.0, 31)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 83) + 3 * pow(2.0, 31)) == (1U << 31));
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 84)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 84) + pow(2.0, 31)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint32_t>(pow(2.0, 84) + pow(2.0, 32)) == 0);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToUint32Large)
|
||||
|
||||
BEGIN_TEST(testToUint64Large)
|
||||
{
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 115)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 115) + pow(2.0, 63)) == (1ULL << 63));
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 115) + 2 * pow(2.0, 63)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 115) + 3 * pow(2.0, 63)) == (1ULL << 63));
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 116)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 116) + pow(2.0, 63)) == 0);
|
||||
CHECK(ToUnsignedInteger<uint64_t>(pow(2.0, 116) + pow(2.0, 64)) == 0);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testToUint64Large)
|
Загрузка…
Ссылка в новой задаче