/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
*/
/* 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 "mozilla/FloatingPoint.h" // mozilla::{PositiveInfinity,UnspecifiedNaN}
#include <stddef.h> // size_t
#include <string.h> // memcmp, memset
#include "js/Conversions.h" // JS::NumberToString, JS::MaximumNumberToStringLength
#include "jsapi-tests/tests.h" // BEGIN_TEST, CHECK_EQUAL, END_TEST
#include "util/Text.h" // js_strlen
#define REST(x) x, (js_strlen(x)), __LINE__
static const struct NumberToStringTest {
double number;
const char * expected;
size_t expectedLength;
size_t lineno;
} numberToStringTests[] = {
{5e-324, REST("5e-324" )}, // 2**-1074
{9.5367431640625e-7, REST("9.5367431640625e-7" )}, // 2**-20
{0.0000010984284297360395, REST("0.0000010984284297360395" )},
{0.0000019073486328125, REST("0.0000019073486328125" )}, // 2**-19
{0.000003814697265625, REST("0.000003814697265625" )}, // 2**-18
{0.0000057220458984375, REST("0.0000057220458984375" )}, // 2**-18 + 2**-19
{0.000244140625, REST("0.000244140625" )}, // 2**-12
{0.125, REST("0.125" )},
{0.25, REST("0.25" )},
{0.5, REST("0.5" )},
{1, REST("1" )},
{1.5, REST("1.5" )},
{2, REST("2" )},
{9, REST("9" )},
{10, REST("10" )},
{15, REST("15" )},
{16, REST("16" )},
{389427, REST("389427" )},
{1073741823, REST("1073741823" )},
{1073741824, REST("1073741824" )},
{1073741825, REST("1073741825" )},
{2147483647, REST("2147483647" )},
{2147483648, REST("2147483648" )},
{2147483649, REST("2147483649" )},
{4294967294, REST("4294967294" )},
{4294967295, REST("4294967295" )},
{4294967296, REST("4294967296" )},
{999999999999999900000.0, REST("999999999999999900000" )},
{999999999999999900000.0 + 65535, REST("999999999999999900000" )},
{999999999999999900000.0 + 65536, REST("1e+21" )},
{1.7976931348623157e+308, REST("1.7976931348623157e+308" )}, // MAX_VALUE
};
static constexpr char PoisonChar = 0x37;
struct StorageForNumberToString {
char out[JS::MaximumNumberToStringLength];
char overflow;
} storage;
BEGIN_TEST(testNumberToString) {
StorageForNumberToString storage;
if (!testNormalValues(false , storage)) {
return false ;
}
if (!testNormalValues(true , storage)) {
return false ;
}
NumberToStringTest zeroTest = {0.0, REST("0" )};
if (!testOne(zeroTest, false , storage)) {
return false ;
}
NumberToStringTest negativeZeroTest = {-0.0, REST("0" )};
if (!testOne(negativeZeroTest, false , storage)) {
return false ;
}
NumberToStringTest infTest = {mozilla::PositiveInfinity<double >(),
REST("Infinity" )};
if (!testOne(infTest, false , storage)) {
return false ;
}
if (!testOne(infTest, true , storage)) {
return false ;
}
NumberToStringTest nanTest = {mozilla::UnspecifiedNaN<double >(), REST("NaN" )};
return testOne(nanTest, false , storage);
}
bool testNormalValues(bool hasMinusSign, StorageForNumberToString& storage) {
for (const auto & test : numberToStringTests) {
if (!testOne(test, hasMinusSign, storage)) {
return false ;
}
}
return true ;
}
bool testOne(const NumberToStringTest& test, bool hasMinusSign,
StorageForNumberToString& storage) {
memset(&storage, PoisonChar, sizeof (storage));
JS::NumberToString(hasMinusSign ? -test.number : test.number, storage.out);
CHECK_EQUAL(storage.overflow, PoisonChar);
const char * start = storage.out;
if (hasMinusSign) {
CHECK_EQUAL(start[0], '-' );
start++;
}
if (!checkEqual(memcmp(start, test.expected, test.expectedLength), 0, start,
test.expected, __FILE__, test.lineno)) {
return false ;
}
char actualTerminator[] = {start[test.expectedLength], '\0' };
return checkEqual(actualTerminator[0], '\0' , actualTerminator, "'\\0'" ,
__FILE__, test.lineno);
}
END_TEST(testNumberToString)
#undef REST
quality 97%
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland