File: PreciseSum.cpp

package info (click to toggle)
wpewebkit 2.50.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 438,176 kB
  • sloc: cpp: 3,776,128; javascript: 197,881; ansic: 156,930; python: 49,118; asm: 21,987; ruby: 18,540; perl: 16,723; xml: 4,623; yacc: 2,360; sh: 2,096; java: 2,019; lex: 1,327; pascal: 366; makefile: 90
file content (127 lines) | stat: -rw-r--r-- 6,011 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Copyright (C) 2025 Keita Nonaka <iKonnyaku40@gmail.com>.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <wtf/PreciseSum.h>

#include <array>

namespace TestWebKitAPI {

static constexpr double Infinity = std::numeric_limits<double>::infinity();
static constexpr double NaN = std::numeric_limits<double>::quiet_NaN();

static const std::array<std::pair<std::vector<double>, double>, 38> TEST_CASES = { {
    { { 1, 2, 3 }, 6 },
    { { 1e308 }, 1e308 },
    { { 1e308, -1e308 }, 0 },
    { { 0.1 }, 0.1 },
    { { 0.1, 0.1 }, 0.2 },
    { { 0.1, -0.1 }, 0 },
    { { 1e308, 1e308, 0.1, 0.1, 1e30, 0.1, -1e30, -1e308, -1e308 }, 0.30000000000000004 },
    { { 1e30, 0.1, -1e30 }, 0.1 },

    { { 8.98846567431158e+307, 8.988465674311579e+307, -1.7976931348623157e+308 }, 9.9792015476736e+291 },
    { { -5.630637621603525e+255, 9.565271205476345e+307, 2.9937604643020797e+292 }, 9.565271205476347e+307 },
    { { 6.739986666787661e+66, 2, -1.2689709186578243e-116, 1.7046015739467354e+308, -9.979201547673601e+291, 6.160926733208294e+307, -3.179557053031852e+234, -7.027282978772846e+307, -0.7500000000000001 }, 1.61796594939028e+308 },
    { { 0.31150493246968836, -8.988465674311582e+307, 1.8315037361673755e-270, -15.999999999999996, 2.9999999999999996, 7.345200721499384e+164, -2.033582473639399, -8.98846567431158e+307, -3.5737295155405993e+292, 4.13894772383715e-124, -3.6111186457260667e-35, 2.387234887098013e+180, 7.645295562778372e-298, 3.395189016861822e-103, -2.6331611115768973e-149 }, -Infinity },
    { { -1.1442589134409902e+308, 9.593842098384855e+138, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307 }, -1.5936821971565685e+308 },
    { { -1.1442589134409902e+308, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307 }, -1.5936821971565687e+308 },
    { { 9.593842098384855e+138, -6.948356297254111e+307, -1.3482698511467367e+308, 4.494232837155792e+307 }, -1.5936821971565685e+308 },
    { { -2.534858246857893e+115, 8.988465674311579e+307, 8.98846567431158e+307 }, 1.7976931348623157e+308 },
    { { 1.3588124894186193e+308, 1.4803986201152006e+223, 6.741349255733684e+307 }, Infinity },
    { { 6.741349255733684e+307, 1.7976931348623155e+308, -7.388327292663961e+41 }, Infinity },
    { { -1.9807040628566093e+28, 1.7976931348623157e+308, 9.9792015476736e+291 }, 1.7976931348623157e+308 },
    { { -1.0214557991173964e+61, 1.7976931348623157e+308, 8.98846567431158e+307, -8.988465674311579e+307 }, 1.7976931348623157e+308 },
    { { 1.7976931348623157e+308, 7.999999999999999, -1.908963895403937e-230, 1.6445950082320264e+292, 2.0734856707605806e+205 }, Infinity },
    { { 6.197409167220438e-223, -9.979201547673601e+291, -1.7976931348623157e+308 }, -Infinity },
    { { 4.49423283715579e+307, 8.944251746776101e+307, -0.0002441406250000001, 1.1752060710043817e+308, 4.940846717201632e+292, -1.6836699406454528e+308 }, 8.353845887521184e+307 },
    { { 8.988465674311579e+307, 7.999999999999998, 7.029158107234023e-308, -2.2303483759420562e-172, -1.7976931348623157e+308, -8.98846567431158e+307 }, -1.7976931348623157e+308 },
    { { 8.98846567431158e+307, 8.98846567431158e+307 }, Infinity },

    { { NaN }, NaN },
    { { Infinity, -Infinity }, NaN },
    { { -Infinity, Infinity }, NaN },

    { { Infinity }, Infinity },
    { { Infinity, Infinity }, Infinity },
    { { -Infinity }, -Infinity },
    { { -Infinity, -Infinity }, -Infinity },

    { { }, -0 },
    { { 0 }, 0 },
    { { -0 }, -0 },
    { { -0, -0 }, -0 },
    { { -0, 0 }, 0 },
    { { 0, 0 }, 0 },
} };

static void shouldBeEqual(double actual, double expected)
{
    if (std::isnan(expected))
        EXPECT_TRUE(std::isnan(actual));
    else
        EXPECT_DOUBLE_EQ(actual, expected);
}

TEST(WTF_PreciseSum, XsumSmall_add)
{
    for (const auto& [input, expected] : TEST_CASES) {
        PreciseSum<WTF::Xsum::XsumSmall> sum;
        for (const auto v : input)
            sum.add(v);
        shouldBeEqual(sum.compute(), expected);
    }
}

TEST(WTF_PreciseSum, XsumSmall_addList)
{
    for (const auto& [input, expected] : TEST_CASES) {
        PreciseSum<WTF::Xsum::XsumSmall> sum;
        sum.addList(input);
        shouldBeEqual(sum.compute(), expected);
    }
}

TEST(WTF_PreciseSum, XsumLarge_add)
{
    for (const auto& [input, expected] : TEST_CASES) {
        PreciseSum<WTF::Xsum::XsumLarge> sum;
        for (const auto v : input)
            sum.add(v);
        shouldBeEqual(sum.compute(), expected);
    }
}

TEST(WTF_PreciseSum, XsumLarge_addList)
{
    for (const auto& [input, expected] : TEST_CASES) {
        PreciseSum<WTF::Xsum::XsumLarge> sum;
        sum.addList(input);
        shouldBeEqual(sum.compute(), expected);
    }
}

} // namespace TestWebKitAPI