1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/tests/TestFloatingPoint.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,523 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/FloatingPoint.h" 1.10 + 1.11 +#include <math.h> 1.12 + 1.13 +using mozilla::ExponentComponent; 1.14 +using mozilla::FloatingPoint; 1.15 +using mozilla::FuzzyEqualsAdditive; 1.16 +using mozilla::FuzzyEqualsMultiplicative; 1.17 +using mozilla::IsFinite; 1.18 +using mozilla::IsInfinite; 1.19 +using mozilla::IsNaN; 1.20 +using mozilla::IsNegative; 1.21 +using mozilla::IsNegativeZero; 1.22 +using mozilla::NegativeInfinity; 1.23 +using mozilla::NumberEqualsInt32; 1.24 +using mozilla::NumberIsInt32; 1.25 +using mozilla::NumbersAreIdentical; 1.26 +using mozilla::PositiveInfinity; 1.27 +using mozilla::SpecificNaN; 1.28 +using mozilla::UnspecifiedNaN; 1.29 + 1.30 +template<typename T> 1.31 +static void 1.32 +ShouldBeIdentical(T d1, T d2) 1.33 +{ 1.34 + MOZ_RELEASE_ASSERT(NumbersAreIdentical(d1, d2)); 1.35 + MOZ_RELEASE_ASSERT(NumbersAreIdentical(d2, d1)); 1.36 +} 1.37 + 1.38 +template<typename T> 1.39 +static void 1.40 +ShouldNotBeIdentical(T d1, T d2) 1.41 +{ 1.42 + MOZ_RELEASE_ASSERT(!NumbersAreIdentical(d1, d2)); 1.43 + MOZ_RELEASE_ASSERT(!NumbersAreIdentical(d2, d1)); 1.44 +} 1.45 + 1.46 +static void 1.47 +TestDoublesAreIdentical() 1.48 +{ 1.49 + ShouldBeIdentical(+0.0, +0.0); 1.50 + ShouldBeIdentical(-0.0, -0.0); 1.51 + ShouldNotBeIdentical(+0.0, -0.0); 1.52 + 1.53 + ShouldBeIdentical(1.0, 1.0); 1.54 + ShouldNotBeIdentical(-1.0, 1.0); 1.55 + ShouldBeIdentical(4294967295.0, 4294967295.0); 1.56 + ShouldNotBeIdentical(-4294967295.0, 4294967295.0); 1.57 + ShouldBeIdentical(4294967296.0, 4294967296.0); 1.58 + ShouldBeIdentical(4294967297.0, 4294967297.0); 1.59 + ShouldBeIdentical(1e300, 1e300); 1.60 + 1.61 + ShouldBeIdentical(PositiveInfinity<double>(), PositiveInfinity<double>()); 1.62 + ShouldBeIdentical(NegativeInfinity<double>(), NegativeInfinity<double>()); 1.63 + ShouldNotBeIdentical(PositiveInfinity<double>(), NegativeInfinity<double>()); 1.64 + 1.65 + ShouldNotBeIdentical(-0.0, NegativeInfinity<double>()); 1.66 + ShouldNotBeIdentical(+0.0, NegativeInfinity<double>()); 1.67 + ShouldNotBeIdentical(1e300, NegativeInfinity<double>()); 1.68 + ShouldNotBeIdentical(3.141592654, NegativeInfinity<double>()); 1.69 + 1.70 + ShouldBeIdentical(UnspecifiedNaN<double>(), UnspecifiedNaN<double>()); 1.71 + ShouldBeIdentical(-UnspecifiedNaN<double>(), UnspecifiedNaN<double>()); 1.72 + ShouldBeIdentical(UnspecifiedNaN<double>(), -UnspecifiedNaN<double>()); 1.73 + 1.74 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 42)); 1.75 + ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(1, 42)); 1.76 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(1, 42)); 1.77 + ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 42)); 1.78 + 1.79 + const uint64_t Mask = 0xfffffffffffffULL; 1.80 + for (unsigned i = 0; i < 52; i++) { 1.81 + for (unsigned j = 0; j < 52; j++) { 1.82 + for (unsigned sign = 0; i < 2; i++) { 1.83 + ShouldBeIdentical(SpecificNaN<double>(0, 1ULL << i), SpecificNaN<double>(sign, 1ULL << j)); 1.84 + ShouldBeIdentical(SpecificNaN<double>(1, 1ULL << i), SpecificNaN<double>(sign, 1ULL << j)); 1.85 + 1.86 + ShouldBeIdentical(SpecificNaN<double>(0, Mask & ~(1ULL << i)), 1.87 + SpecificNaN<double>(sign, Mask & ~(1ULL << j))); 1.88 + ShouldBeIdentical(SpecificNaN<double>(1, Mask & ~(1ULL << i)), 1.89 + SpecificNaN<double>(sign, Mask & ~(1ULL << j))); 1.90 + } 1.91 + } 1.92 + } 1.93 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x8000000000000ULL)); 1.94 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x4000000000000ULL)); 1.95 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x2000000000000ULL)); 1.96 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x1000000000000ULL)); 1.97 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0800000000000ULL)); 1.98 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0400000000000ULL)); 1.99 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0200000000000ULL)); 1.100 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0100000000000ULL)); 1.101 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0080000000000ULL)); 1.102 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0040000000000ULL)); 1.103 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0020000000000ULL)); 1.104 + ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0010000000000ULL)); 1.105 + ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 0xff0ffffffffffULL)); 1.106 + ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 0xfffffffffff0fULL)); 1.107 + 1.108 + ShouldNotBeIdentical(UnspecifiedNaN<double>(), +0.0); 1.109 + ShouldNotBeIdentical(UnspecifiedNaN<double>(), -0.0); 1.110 + ShouldNotBeIdentical(UnspecifiedNaN<double>(), 1.0); 1.111 + ShouldNotBeIdentical(UnspecifiedNaN<double>(), -1.0); 1.112 + ShouldNotBeIdentical(UnspecifiedNaN<double>(), PositiveInfinity<double>()); 1.113 + ShouldNotBeIdentical(UnspecifiedNaN<double>(), NegativeInfinity<double>()); 1.114 +} 1.115 + 1.116 +static void 1.117 +TestFloatsAreIdentical() 1.118 +{ 1.119 + ShouldBeIdentical(+0.0f, +0.0f); 1.120 + ShouldBeIdentical(-0.0f, -0.0f); 1.121 + ShouldNotBeIdentical(+0.0f, -0.0f); 1.122 + 1.123 + ShouldBeIdentical(1.0f, 1.0f); 1.124 + ShouldNotBeIdentical(-1.0f, 1.0f); 1.125 + ShouldBeIdentical(8388607.0f, 8388607.0f); 1.126 + ShouldNotBeIdentical(-8388607.0f, 8388607.0f); 1.127 + ShouldBeIdentical(8388608.0f, 8388608.0f); 1.128 + ShouldBeIdentical(8388609.0f, 8388609.0f); 1.129 + ShouldBeIdentical(1e36f, 1e36f); 1.130 + 1.131 + ShouldBeIdentical(PositiveInfinity<float>(), PositiveInfinity<float>()); 1.132 + ShouldBeIdentical(NegativeInfinity<float>(), NegativeInfinity<float>()); 1.133 + ShouldNotBeIdentical(PositiveInfinity<float>(), NegativeInfinity<float>()); 1.134 + 1.135 + ShouldNotBeIdentical(-0.0f, NegativeInfinity<float>()); 1.136 + ShouldNotBeIdentical(+0.0f, NegativeInfinity<float>()); 1.137 + ShouldNotBeIdentical(1e36f, NegativeInfinity<float>()); 1.138 + ShouldNotBeIdentical(3.141592654f, NegativeInfinity<float>()); 1.139 + 1.140 + ShouldBeIdentical(UnspecifiedNaN<float>(), UnspecifiedNaN<float>()); 1.141 + ShouldBeIdentical(-UnspecifiedNaN<float>(), UnspecifiedNaN<float>()); 1.142 + ShouldBeIdentical(UnspecifiedNaN<float>(), -UnspecifiedNaN<float>()); 1.143 + 1.144 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 42)); 1.145 + ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(1, 42)); 1.146 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(1, 42)); 1.147 + ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(0, 42)); 1.148 + 1.149 + const uint32_t Mask = 0x7fffffUL; 1.150 + for (unsigned i = 0; i < 23; i++) { 1.151 + for (unsigned j = 0; j < 23; j++) { 1.152 + for (unsigned sign = 0; i < 2; i++) { 1.153 + ShouldBeIdentical(SpecificNaN<float>(0, 1UL << i), SpecificNaN<float>(sign, 1UL << j)); 1.154 + ShouldBeIdentical(SpecificNaN<float>(1, 1UL << i), SpecificNaN<float>(sign, 1UL << j)); 1.155 + 1.156 + ShouldBeIdentical(SpecificNaN<float>(0, Mask & ~(1UL << i)), 1.157 + SpecificNaN<float>(sign, Mask & ~(1UL << j))); 1.158 + ShouldBeIdentical(SpecificNaN<float>(1, Mask & ~(1UL << i)), 1.159 + SpecificNaN<float>(sign, Mask & ~(1UL << j))); 1.160 + } 1.161 + } 1.162 + } 1.163 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x700000)); 1.164 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x400000)); 1.165 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x200000)); 1.166 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x100000)); 1.167 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x080000)); 1.168 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x040000)); 1.169 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x020000)); 1.170 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x010000)); 1.171 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x008000)); 1.172 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x004000)); 1.173 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x002000)); 1.174 + ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x001000)); 1.175 + ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(0, 0x7f0fff)); 1.176 + ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(0, 0x7fff0f)); 1.177 + 1.178 + ShouldNotBeIdentical(UnspecifiedNaN<float>(), +0.0f); 1.179 + ShouldNotBeIdentical(UnspecifiedNaN<float>(), -0.0f); 1.180 + ShouldNotBeIdentical(UnspecifiedNaN<float>(), 1.0f); 1.181 + ShouldNotBeIdentical(UnspecifiedNaN<float>(), -1.0f); 1.182 + ShouldNotBeIdentical(UnspecifiedNaN<float>(), PositiveInfinity<float>()); 1.183 + ShouldNotBeIdentical(UnspecifiedNaN<float>(), NegativeInfinity<float>()); 1.184 +} 1.185 + 1.186 +static void 1.187 +TestAreIdentical() 1.188 +{ 1.189 + TestDoublesAreIdentical(); 1.190 + TestFloatsAreIdentical(); 1.191 +} 1.192 + 1.193 +static void 1.194 +TestDoubleExponentComponent() 1.195 +{ 1.196 + MOZ_RELEASE_ASSERT(ExponentComponent(0.0) == -int_fast16_t(FloatingPoint<double>::ExponentBias)); 1.197 + MOZ_RELEASE_ASSERT(ExponentComponent(-0.0) == -int_fast16_t(FloatingPoint<double>::ExponentBias)); 1.198 + MOZ_RELEASE_ASSERT(ExponentComponent(0.125) == -3); 1.199 + MOZ_RELEASE_ASSERT(ExponentComponent(0.5) == -1); 1.200 + MOZ_RELEASE_ASSERT(ExponentComponent(1.0) == 0); 1.201 + MOZ_RELEASE_ASSERT(ExponentComponent(1.5) == 0); 1.202 + MOZ_RELEASE_ASSERT(ExponentComponent(2.0) == 1); 1.203 + MOZ_RELEASE_ASSERT(ExponentComponent(7.0) == 2); 1.204 + MOZ_RELEASE_ASSERT(ExponentComponent(PositiveInfinity<double>()) == FloatingPoint<double>::ExponentBias + 1); 1.205 + MOZ_RELEASE_ASSERT(ExponentComponent(NegativeInfinity<double>()) == FloatingPoint<double>::ExponentBias + 1); 1.206 + MOZ_RELEASE_ASSERT(ExponentComponent(UnspecifiedNaN<double>()) == FloatingPoint<double>::ExponentBias + 1); 1.207 +} 1.208 + 1.209 +static void 1.210 +TestFloatExponentComponent() 1.211 +{ 1.212 + MOZ_RELEASE_ASSERT(ExponentComponent(0.0f) == -int_fast16_t(FloatingPoint<float>::ExponentBias)); 1.213 + MOZ_RELEASE_ASSERT(ExponentComponent(-0.0f) == -int_fast16_t(FloatingPoint<float>::ExponentBias)); 1.214 + MOZ_RELEASE_ASSERT(ExponentComponent(0.125f) == -3); 1.215 + MOZ_RELEASE_ASSERT(ExponentComponent(0.5f) == -1); 1.216 + MOZ_RELEASE_ASSERT(ExponentComponent(1.0f) == 0); 1.217 + MOZ_RELEASE_ASSERT(ExponentComponent(1.5f) == 0); 1.218 + MOZ_RELEASE_ASSERT(ExponentComponent(2.0f) == 1); 1.219 + MOZ_RELEASE_ASSERT(ExponentComponent(7.0f) == 2); 1.220 + MOZ_RELEASE_ASSERT(ExponentComponent(PositiveInfinity<float>()) == FloatingPoint<float>::ExponentBias + 1); 1.221 + MOZ_RELEASE_ASSERT(ExponentComponent(NegativeInfinity<float>()) == FloatingPoint<float>::ExponentBias + 1); 1.222 + MOZ_RELEASE_ASSERT(ExponentComponent(UnspecifiedNaN<float>()) == FloatingPoint<float>::ExponentBias + 1); 1.223 +} 1.224 + 1.225 +static void 1.226 +TestExponentComponent() 1.227 +{ 1.228 + TestDoubleExponentComponent(); 1.229 + TestFloatExponentComponent(); 1.230 +} 1.231 + 1.232 +static void 1.233 +TestDoublesPredicates() 1.234 +{ 1.235 + MOZ_RELEASE_ASSERT(IsNaN(UnspecifiedNaN<double>())); 1.236 + MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<double>(1, 17)));; 1.237 + MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<double>(0, 0xfffffffffff0fULL))); 1.238 + MOZ_RELEASE_ASSERT(!IsNaN(0.0)); 1.239 + MOZ_RELEASE_ASSERT(!IsNaN(-0.0)); 1.240 + MOZ_RELEASE_ASSERT(!IsNaN(1.0)); 1.241 + MOZ_RELEASE_ASSERT(!IsNaN(PositiveInfinity<double>())); 1.242 + MOZ_RELEASE_ASSERT(!IsNaN(NegativeInfinity<double>())); 1.243 + 1.244 + MOZ_RELEASE_ASSERT(IsInfinite(PositiveInfinity<double>())); 1.245 + MOZ_RELEASE_ASSERT(IsInfinite(NegativeInfinity<double>())); 1.246 + MOZ_RELEASE_ASSERT(!IsInfinite(UnspecifiedNaN<double>())); 1.247 + MOZ_RELEASE_ASSERT(!IsInfinite(0.0)); 1.248 + MOZ_RELEASE_ASSERT(!IsInfinite(-0.0)); 1.249 + MOZ_RELEASE_ASSERT(!IsInfinite(1.0)); 1.250 + 1.251 + MOZ_RELEASE_ASSERT(!IsFinite(PositiveInfinity<double>())); 1.252 + MOZ_RELEASE_ASSERT(!IsFinite(NegativeInfinity<double>())); 1.253 + MOZ_RELEASE_ASSERT(!IsFinite(UnspecifiedNaN<double>())); 1.254 + MOZ_RELEASE_ASSERT(IsFinite(0.0)); 1.255 + MOZ_RELEASE_ASSERT(IsFinite(-0.0)); 1.256 + MOZ_RELEASE_ASSERT(IsFinite(1.0)); 1.257 + 1.258 + MOZ_RELEASE_ASSERT(!IsNegative(PositiveInfinity<double>())); 1.259 + MOZ_RELEASE_ASSERT(IsNegative(NegativeInfinity<double>())); 1.260 + MOZ_RELEASE_ASSERT(IsNegative(-0.0)); 1.261 + MOZ_RELEASE_ASSERT(!IsNegative(0.0)); 1.262 + MOZ_RELEASE_ASSERT(IsNegative(-1.0)); 1.263 + MOZ_RELEASE_ASSERT(!IsNegative(1.0)); 1.264 + 1.265 + MOZ_RELEASE_ASSERT(!IsNegativeZero(PositiveInfinity<double>())); 1.266 + MOZ_RELEASE_ASSERT(!IsNegativeZero(NegativeInfinity<double>())); 1.267 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(1, 17)));; 1.268 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(1, 0xfffffffffff0fULL))); 1.269 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(0, 17)));; 1.270 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(0, 0xfffffffffff0fULL))); 1.271 + MOZ_RELEASE_ASSERT(!IsNegativeZero(UnspecifiedNaN<double>())); 1.272 + MOZ_RELEASE_ASSERT(IsNegativeZero(-0.0)); 1.273 + MOZ_RELEASE_ASSERT(!IsNegativeZero(0.0)); 1.274 + MOZ_RELEASE_ASSERT(!IsNegativeZero(-1.0)); 1.275 + MOZ_RELEASE_ASSERT(!IsNegativeZero(1.0)); 1.276 + 1.277 + int32_t i; 1.278 + MOZ_RELEASE_ASSERT(NumberIsInt32(0.0, &i)); MOZ_RELEASE_ASSERT(i == 0); 1.279 + MOZ_RELEASE_ASSERT(!NumberIsInt32(-0.0, &i)); 1.280 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(0.0, &i)); MOZ_RELEASE_ASSERT(i == 0); 1.281 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(-0.0, &i)); MOZ_RELEASE_ASSERT(i == 0); 1.282 + MOZ_RELEASE_ASSERT(NumberIsInt32(double(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); 1.283 + MOZ_RELEASE_ASSERT(NumberIsInt32(double(INT32_MAX), &i)); MOZ_RELEASE_ASSERT(i == INT32_MAX); 1.284 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(double(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); 1.285 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(double(INT32_MAX), &i)); MOZ_RELEASE_ASSERT(i == INT32_MAX); 1.286 + MOZ_RELEASE_ASSERT(!NumberIsInt32(0.5, &i)); 1.287 + MOZ_RELEASE_ASSERT(!NumberIsInt32(double(INT32_MAX) + 0.1, &i)); 1.288 + MOZ_RELEASE_ASSERT(!NumberIsInt32(double(INT32_MIN) - 0.1, &i)); 1.289 + MOZ_RELEASE_ASSERT(!NumberIsInt32(NegativeInfinity<double>(), &i)); 1.290 + MOZ_RELEASE_ASSERT(!NumberIsInt32(PositiveInfinity<double>(), &i)); 1.291 + MOZ_RELEASE_ASSERT(!NumberIsInt32(UnspecifiedNaN<double>(), &i)); 1.292 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(0.5, &i)); 1.293 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(double(INT32_MAX) + 0.1, &i)); 1.294 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(double(INT32_MIN) - 0.1, &i)); 1.295 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(NegativeInfinity<double>(), &i)); 1.296 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(PositiveInfinity<double>(), &i)); 1.297 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(UnspecifiedNaN<double>(), &i)); 1.298 +} 1.299 + 1.300 +static void 1.301 +TestFloatsPredicates() 1.302 +{ 1.303 + MOZ_RELEASE_ASSERT(IsNaN(UnspecifiedNaN<float>())); 1.304 + MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<float>(1, 17)));; 1.305 + MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<float>(0, 0x7fff0fUL))); 1.306 + MOZ_RELEASE_ASSERT(!IsNaN(0.0f)); 1.307 + MOZ_RELEASE_ASSERT(!IsNaN(-0.0f)); 1.308 + MOZ_RELEASE_ASSERT(!IsNaN(1.0f)); 1.309 + MOZ_RELEASE_ASSERT(!IsNaN(PositiveInfinity<float>())); 1.310 + MOZ_RELEASE_ASSERT(!IsNaN(NegativeInfinity<float>())); 1.311 + 1.312 + MOZ_RELEASE_ASSERT(IsInfinite(PositiveInfinity<float>())); 1.313 + MOZ_RELEASE_ASSERT(IsInfinite(NegativeInfinity<float>())); 1.314 + MOZ_RELEASE_ASSERT(!IsInfinite(UnspecifiedNaN<float>())); 1.315 + MOZ_RELEASE_ASSERT(!IsInfinite(0.0f)); 1.316 + MOZ_RELEASE_ASSERT(!IsInfinite(-0.0f)); 1.317 + MOZ_RELEASE_ASSERT(!IsInfinite(1.0f)); 1.318 + 1.319 + MOZ_RELEASE_ASSERT(!IsFinite(PositiveInfinity<float>())); 1.320 + MOZ_RELEASE_ASSERT(!IsFinite(NegativeInfinity<float>())); 1.321 + MOZ_RELEASE_ASSERT(!IsFinite(UnspecifiedNaN<float>())); 1.322 + MOZ_RELEASE_ASSERT(IsFinite(0.0f)); 1.323 + MOZ_RELEASE_ASSERT(IsFinite(-0.0f)); 1.324 + MOZ_RELEASE_ASSERT(IsFinite(1.0f)); 1.325 + 1.326 + MOZ_RELEASE_ASSERT(!IsNegative(PositiveInfinity<float>())); 1.327 + MOZ_RELEASE_ASSERT(IsNegative(NegativeInfinity<float>())); 1.328 + MOZ_RELEASE_ASSERT(IsNegative(-0.0f)); 1.329 + MOZ_RELEASE_ASSERT(!IsNegative(0.0f)); 1.330 + MOZ_RELEASE_ASSERT(IsNegative(-1.0f)); 1.331 + MOZ_RELEASE_ASSERT(!IsNegative(1.0f)); 1.332 + 1.333 + MOZ_RELEASE_ASSERT(!IsNegativeZero(PositiveInfinity<float>())); 1.334 + MOZ_RELEASE_ASSERT(!IsNegativeZero(NegativeInfinity<float>())); 1.335 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(1, 17)));; 1.336 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(1, 0x7fff0fUL))); 1.337 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(0, 17)));; 1.338 + MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(0, 0x7fff0fUL))); 1.339 + MOZ_RELEASE_ASSERT(!IsNegativeZero(UnspecifiedNaN<float>())); 1.340 + MOZ_RELEASE_ASSERT(IsNegativeZero(-0.0f)); 1.341 + MOZ_RELEASE_ASSERT(!IsNegativeZero(0.0f)); 1.342 + MOZ_RELEASE_ASSERT(!IsNegativeZero(-1.0f)); 1.343 + MOZ_RELEASE_ASSERT(!IsNegativeZero(1.0f)); 1.344 + 1.345 + int32_t i; 1.346 + const int32_t BIG = 2097151; 1.347 + MOZ_RELEASE_ASSERT(NumberIsInt32(0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0); 1.348 + MOZ_RELEASE_ASSERT(!NumberIsInt32(-0.0f, &i)); 1.349 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0); 1.350 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(-0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0); 1.351 + MOZ_RELEASE_ASSERT(NumberIsInt32(float(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); 1.352 + MOZ_RELEASE_ASSERT(NumberIsInt32(float(BIG), &i)); MOZ_RELEASE_ASSERT(i == BIG); 1.353 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(float(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); 1.354 + MOZ_RELEASE_ASSERT(NumberEqualsInt32(float(BIG), &i)); MOZ_RELEASE_ASSERT(i == BIG); 1.355 + MOZ_RELEASE_ASSERT(!NumberIsInt32(0.5f, &i)); 1.356 + MOZ_RELEASE_ASSERT(!NumberIsInt32(float(BIG) + 0.1f, &i)); 1.357 + MOZ_RELEASE_ASSERT(!NumberIsInt32(NegativeInfinity<float>(), &i)); 1.358 + MOZ_RELEASE_ASSERT(!NumberIsInt32(PositiveInfinity<float>(), &i)); 1.359 + MOZ_RELEASE_ASSERT(!NumberIsInt32(UnspecifiedNaN<float>(), &i)); 1.360 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(0.5f, &i)); 1.361 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(float(BIG) + 0.1f, &i)); 1.362 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(NegativeInfinity<float>(), &i)); 1.363 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(PositiveInfinity<float>(), &i)); 1.364 + MOZ_RELEASE_ASSERT(!NumberEqualsInt32(UnspecifiedNaN<float>(), &i)); 1.365 +} 1.366 + 1.367 +static void 1.368 +TestPredicates() 1.369 +{ 1.370 + TestFloatsPredicates(); 1.371 + TestDoublesPredicates(); 1.372 +} 1.373 + 1.374 +static void 1.375 +TestFloatsAreApproximatelyEqual() 1.376 +{ 1.377 + float epsilon = mozilla::detail::FuzzyEqualsEpsilon<float>::value(); 1.378 + float lessThanEpsilon = epsilon / 2.0f; 1.379 + float moreThanEpsilon = epsilon * 2.0f; 1.380 + 1.381 + // Additive tests using the default epsilon 1.382 + // ... around 1.0 1.383 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f + lessThanEpsilon)); 1.384 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f - lessThanEpsilon)); 1.385 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f + epsilon)); 1.386 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f - epsilon)); 1.387 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0f, 1.0f + moreThanEpsilon)); 1.388 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0f, 1.0f - moreThanEpsilon)); 1.389 + // ... around 1.0e2 (this is near the upper bound of the range where 1.390 + // adding moreThanEpsilon will still be representable and return false) 1.391 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + lessThanEpsilon)); 1.392 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + epsilon)); 1.393 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e2f, 1.0e2f + moreThanEpsilon)); 1.394 + // ... around 1.0e-10 1.395 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + lessThanEpsilon)); 1.396 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + epsilon)); 1.397 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + moreThanEpsilon)); 1.398 + // ... straddling 0 1.399 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-6f, -1.0e-6f)); 1.400 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-5f, -1.0e-5f)); 1.401 + // Using a small epsilon 1.402 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-9f)); 1.403 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-11f)); 1.404 + // Using a big epsilon 1.405 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e16f)); 1.406 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e14f)); 1.407 + 1.408 + // Multiplicative tests using the default epsilon 1.409 + // ... around 1.0 1.410 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f + lessThanEpsilon)); 1.411 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f - lessThanEpsilon)); 1.412 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f + epsilon)); 1.413 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f - epsilon)); 1.414 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f + moreThanEpsilon)); 1.415 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f - moreThanEpsilon)); 1.416 + // ... around 1.0e10 1.417 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (lessThanEpsilon * 1.0e10f))); 1.418 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (moreThanEpsilon * 1.0e10f))); 1.419 + // ... around 1.0e-10 1.420 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-10f, 1.0e-10f + (lessThanEpsilon * 1.0e-10f))); 1.421 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-10f, 1.0e-10f + (moreThanEpsilon * 1.0e-10f))); 1.422 + // ... straddling 0 1.423 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f)); 1.424 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f, 1.0e2f)); 1.425 + // Using a small epsilon 1.426 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-4f)); 1.427 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-5f)); 1.428 + // Using a big epsilon 1.429 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 2.0f, 1.0f)); 1.430 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 2.0f, 0.1f)); 1.431 + 1.432 + // "real world case" 1.433 + float oneThird = 10.0f / 3.0f; 1.434 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(10.0f, 3.0f * oneThird)); 1.435 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(10.0f, 3.0f * oneThird)); 1.436 + // NaN check 1.437 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1))); 1.438 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 8))); 1.439 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1))); 1.440 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 200))); 1.441 +} 1.442 + 1.443 +static void 1.444 +TestDoublesAreApproximatelyEqual() 1.445 +{ 1.446 + double epsilon = mozilla::detail::FuzzyEqualsEpsilon<double>::value(); 1.447 + double lessThanEpsilon = epsilon / 2.0; 1.448 + double moreThanEpsilon = epsilon * 2.0; 1.449 + 1.450 + // Additive tests using the default epsilon 1.451 + // ... around 1.0 1.452 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 + lessThanEpsilon)); 1.453 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 - lessThanEpsilon)); 1.454 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 + epsilon)); 1.455 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 - epsilon)); 1.456 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0, 1.0 + moreThanEpsilon)); 1.457 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0, 1.0 - moreThanEpsilon)); 1.458 + // ... around 1.0e4 (this is near the upper bound of the range where 1.459 + // adding moreThanEpsilon will still be representable and return false) 1.460 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e4, 1.0e4 + lessThanEpsilon)); 1.461 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e4, 1.0e4 + epsilon)); 1.462 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e4, 1.0e4 + moreThanEpsilon)); 1.463 + // ... around 1.0e-25 1.464 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + lessThanEpsilon)); 1.465 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + epsilon)); 1.466 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + moreThanEpsilon)); 1.467 + // ... straddling 0 1.468 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-13, -1.0e-13)); 1.469 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-12, -1.0e-12)); 1.470 + // Using a small epsilon 1.471 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-29)); 1.472 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-31)); 1.473 + // Using a big epsilon 1.474 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e26)); 1.475 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e24)); 1.476 + 1.477 + // Multiplicative tests using the default epsilon 1.478 + // ... around 1.0 1.479 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 + lessThanEpsilon)); 1.480 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 - lessThanEpsilon)); 1.481 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 + epsilon)); 1.482 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 - epsilon)); 1.483 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 + moreThanEpsilon)); 1.484 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 - moreThanEpsilon)); 1.485 + // ... around 1.0e30 1.486 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (lessThanEpsilon * 1.0e30))); 1.487 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (moreThanEpsilon * 1.0e30))); 1.488 + // ... around 1.0e-30 1.489 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (lessThanEpsilon * 1.0e-30))); 1.490 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (moreThanEpsilon * 1.0e-30))); 1.491 + // ... straddling 0 1.492 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6)); 1.493 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6, 1.0e2)); 1.494 + // Using a small epsilon 1.495 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-15)); 1.496 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-16)); 1.497 + // Using a big epsilon 1.498 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 1.0)); 1.499 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 0.1)); 1.500 + 1.501 + // "real world case" 1.502 + double oneThird = 10.0 / 3.0; 1.503 + MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(10.0, 3.0 * oneThird)); 1.504 + MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(10.0, 3.0 * oneThird)); 1.505 + // NaN check 1.506 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 1), SpecificNaN<double>(1, 1))); 1.507 + MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 2), SpecificNaN<double>(0, 8))); 1.508 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 1), SpecificNaN<double>(1, 1))); 1.509 + MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 2), SpecificNaN<double>(0, 200))); 1.510 +} 1.511 + 1.512 +static void 1.513 +TestAreApproximatelyEqual() 1.514 +{ 1.515 + TestFloatsAreApproximatelyEqual(); 1.516 + TestDoublesAreApproximatelyEqual(); 1.517 +} 1.518 + 1.519 +int 1.520 +main() 1.521 +{ 1.522 + TestAreIdentical(); 1.523 + TestExponentComponent(); 1.524 + TestPredicates(); 1.525 + TestAreApproximatelyEqual(); 1.526 +}