generate_real_test.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/random/internal/generate_real.h"
  15. #include <cfloat>
  16. #include <cstddef>
  17. #include <cstdint>
  18. #include <string>
  19. #include "gtest/gtest.h"
  20. #include "absl/flags/flag.h"
  21. #include "absl/numeric/bits.h"
  22. ABSL_FLAG(int64_t, absl_random_test_trials, 50000,
  23. "Number of trials for the probability tests.");
  24. using absl::random_internal::GenerateNegativeTag;
  25. using absl::random_internal::GeneratePositiveTag;
  26. using absl::random_internal::GenerateRealFromBits;
  27. using absl::random_internal::GenerateSignedTag;
  28. namespace {
  29. TEST(GenerateRealTest, U64ToFloat_Positive_NoZero_Test) {
  30. auto ToFloat = [](uint64_t a) {
  31. return GenerateRealFromBits<float, GeneratePositiveTag, false>(a);
  32. };
  33. EXPECT_EQ(ToFloat(0x0000000000000000), 2.710505431e-20f);
  34. EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f);
  35. EXPECT_EQ(ToFloat(0x8000000000000000), 0.5);
  36. EXPECT_EQ(ToFloat(0x8000000000000001), 0.5);
  37. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f);
  38. }
  39. TEST(GenerateRealTest, U64ToFloat_Positive_Zero_Test) {
  40. auto ToFloat = [](uint64_t a) {
  41. return GenerateRealFromBits<float, GeneratePositiveTag, true>(a);
  42. };
  43. EXPECT_EQ(ToFloat(0x0000000000000000), 0.0);
  44. EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f);
  45. EXPECT_EQ(ToFloat(0x8000000000000000), 0.5);
  46. EXPECT_EQ(ToFloat(0x8000000000000001), 0.5);
  47. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f);
  48. }
  49. TEST(GenerateRealTest, U64ToFloat_Negative_NoZero_Test) {
  50. auto ToFloat = [](uint64_t a) {
  51. return GenerateRealFromBits<float, GenerateNegativeTag, false>(a);
  52. };
  53. EXPECT_EQ(ToFloat(0x0000000000000000), -2.710505431e-20f);
  54. EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f);
  55. EXPECT_EQ(ToFloat(0x8000000000000000), -0.5);
  56. EXPECT_EQ(ToFloat(0x8000000000000001), -0.5);
  57. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f);
  58. }
  59. TEST(GenerateRealTest, U64ToFloat_Negative_Zero_Test) {
  60. auto ToFloat = [](uint64_t a) {
  61. return GenerateRealFromBits<float, GenerateNegativeTag, true>(a);
  62. };
  63. EXPECT_EQ(ToFloat(0x0000000000000000), 0.0);
  64. EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f);
  65. EXPECT_EQ(ToFloat(0x8000000000000000), -0.5);
  66. EXPECT_EQ(ToFloat(0x8000000000000001), -0.5);
  67. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f);
  68. }
  69. TEST(GenerateRealTest, U64ToFloat_Signed_NoZero_Test) {
  70. auto ToFloat = [](uint64_t a) {
  71. return GenerateRealFromBits<float, GenerateSignedTag, false>(a);
  72. };
  73. EXPECT_EQ(ToFloat(0x0000000000000000), 5.421010862e-20f);
  74. EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f);
  75. EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f);
  76. EXPECT_EQ(ToFloat(0x8000000000000000), -5.421010862e-20f);
  77. EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f);
  78. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f);
  79. }
  80. TEST(GenerateRealTest, U64ToFloat_Signed_Zero_Test) {
  81. auto ToFloat = [](uint64_t a) {
  82. return GenerateRealFromBits<float, GenerateSignedTag, true>(a);
  83. };
  84. EXPECT_EQ(ToFloat(0x0000000000000000), 0);
  85. EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f);
  86. EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f);
  87. EXPECT_EQ(ToFloat(0x8000000000000000), 0);
  88. EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f);
  89. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f);
  90. }
  91. TEST(GenerateRealTest, U64ToFloat_Signed_Bias_Test) {
  92. auto ToFloat = [](uint64_t a) {
  93. return GenerateRealFromBits<float, GenerateSignedTag, true>(a, 1);
  94. };
  95. EXPECT_EQ(ToFloat(0x0000000000000000), 0);
  96. EXPECT_EQ(ToFloat(0x0000000000000001), 2 * 1.084202172e-19f);
  97. EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 2 * 0.9999999404f);
  98. EXPECT_EQ(ToFloat(0x8000000000000000), 0);
  99. EXPECT_EQ(ToFloat(0x8000000000000001), 2 * -1.084202172e-19f);
  100. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 2 * -0.9999999404f);
  101. }
  102. TEST(GenerateRealTest, U64ToFloatTest) {
  103. auto ToFloat = [](uint64_t a) -> float {
  104. return GenerateRealFromBits<float, GeneratePositiveTag, true>(a);
  105. };
  106. EXPECT_EQ(ToFloat(0x0000000000000000), 0.0f);
  107. EXPECT_EQ(ToFloat(0x8000000000000000), 0.5f);
  108. EXPECT_EQ(ToFloat(0x8000000000000001), 0.5f);
  109. EXPECT_EQ(ToFloat(0x800000FFFFFFFFFF), 0.5f);
  110. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f);
  111. EXPECT_GT(ToFloat(0x0000000000000001), 0.0f);
  112. EXPECT_NE(ToFloat(0x7FFFFF0000000000), ToFloat(0x7FFFFEFFFFFFFFFF));
  113. EXPECT_LT(ToFloat(0xFFFFFFFFFFFFFFFF), 1.0f);
  114. int32_t two_to_24 = 1 << 24;
  115. EXPECT_EQ(static_cast<int32_t>(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24),
  116. two_to_24 - 1);
  117. EXPECT_NE(static_cast<int32_t>(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24 * 2),
  118. two_to_24 * 2 - 1);
  119. EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFF0000000000));
  120. EXPECT_NE(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFEFFFFFFFFFF));
  121. EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF8000000000));
  122. EXPECT_NE(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF7FFFFFFFFF));
  123. EXPECT_EQ(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFC000000000));
  124. EXPECT_NE(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFBFFFFFFFFF));
  125. // For values where every bit counts, the values scale as multiples of the
  126. // input.
  127. for (int i = 0; i < 100; ++i) {
  128. EXPECT_EQ(i * ToFloat(0x0000000000000001), ToFloat(i));
  129. }
  130. // For each i: value generated from (1 << i).
  131. float exp_values[64];
  132. exp_values[63] = 0.5f;
  133. for (int i = 62; i >= 0; --i) exp_values[i] = 0.5f * exp_values[i + 1];
  134. constexpr uint64_t one = 1;
  135. for (int i = 0; i < 64; ++i) {
  136. EXPECT_EQ(ToFloat(one << i), exp_values[i]);
  137. for (int j = 1; j < FLT_MANT_DIG && i - j >= 0; ++j) {
  138. EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]);
  139. EXPECT_EQ(ToFloat((one << i) + (one << (i - j))),
  140. exp_values[i] + exp_values[i - j]);
  141. }
  142. for (int j = FLT_MANT_DIG; i - j >= 0; ++j) {
  143. EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]);
  144. EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), exp_values[i]);
  145. }
  146. }
  147. }
  148. TEST(GenerateRealTest, U64ToDouble_Positive_NoZero_Test) {
  149. auto ToDouble = [](uint64_t a) {
  150. return GenerateRealFromBits<double, GeneratePositiveTag, false>(a);
  151. };
  152. EXPECT_EQ(ToDouble(0x0000000000000000), 2.710505431213761085e-20);
  153. EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20);
  154. EXPECT_EQ(ToDouble(0x0000000000000002), 1.084202172485504434e-19);
  155. EXPECT_EQ(ToDouble(0x8000000000000000), 0.5);
  156. EXPECT_EQ(ToDouble(0x8000000000000001), 0.5);
  157. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978);
  158. }
  159. TEST(GenerateRealTest, U64ToDouble_Positive_Zero_Test) {
  160. auto ToDouble = [](uint64_t a) {
  161. return GenerateRealFromBits<double, GeneratePositiveTag, true>(a);
  162. };
  163. EXPECT_EQ(ToDouble(0x0000000000000000), 0.0);
  164. EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20);
  165. EXPECT_EQ(ToDouble(0x8000000000000000), 0.5);
  166. EXPECT_EQ(ToDouble(0x8000000000000001), 0.5);
  167. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978);
  168. }
  169. TEST(GenerateRealTest, U64ToDouble_Negative_NoZero_Test) {
  170. auto ToDouble = [](uint64_t a) {
  171. return GenerateRealFromBits<double, GenerateNegativeTag, false>(a);
  172. };
  173. EXPECT_EQ(ToDouble(0x0000000000000000), -2.710505431213761085e-20);
  174. EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20);
  175. EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19);
  176. EXPECT_EQ(ToDouble(0x8000000000000000), -0.5);
  177. EXPECT_EQ(ToDouble(0x8000000000000001), -0.5);
  178. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978);
  179. }
  180. TEST(GenerateRealTest, U64ToDouble_Negative_Zero_Test) {
  181. auto ToDouble = [](uint64_t a) {
  182. return GenerateRealFromBits<double, GenerateNegativeTag, true>(a);
  183. };
  184. EXPECT_EQ(ToDouble(0x0000000000000000), 0.0);
  185. EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20);
  186. EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19);
  187. EXPECT_EQ(ToDouble(0x8000000000000000), -0.5);
  188. EXPECT_EQ(ToDouble(0x8000000000000001), -0.5);
  189. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978);
  190. }
  191. TEST(GenerateRealTest, U64ToDouble_Signed_NoZero_Test) {
  192. auto ToDouble = [](uint64_t a) {
  193. return GenerateRealFromBits<double, GenerateSignedTag, false>(a);
  194. };
  195. EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20);
  196. EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19);
  197. EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978);
  198. EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20);
  199. EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19);
  200. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978);
  201. }
  202. TEST(GenerateRealTest, U64ToDouble_Signed_Zero_Test) {
  203. auto ToDouble = [](uint64_t a) {
  204. return GenerateRealFromBits<double, GenerateSignedTag, true>(a);
  205. };
  206. EXPECT_EQ(ToDouble(0x0000000000000000), 0);
  207. EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19);
  208. EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978);
  209. EXPECT_EQ(ToDouble(0x8000000000000000), 0);
  210. EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19);
  211. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978);
  212. }
  213. TEST(GenerateRealTest, U64ToDouble_GenerateSignedTag_Bias_Test) {
  214. auto ToDouble = [](uint64_t a) {
  215. return GenerateRealFromBits<double, GenerateSignedTag, true>(a, -1);
  216. };
  217. EXPECT_EQ(ToDouble(0x0000000000000000), 0);
  218. EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19 / 2);
  219. EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978 / 2);
  220. EXPECT_EQ(ToDouble(0x8000000000000000), 0);
  221. EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19 / 2);
  222. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978 / 2);
  223. }
  224. TEST(GenerateRealTest, U64ToDoubleTest) {
  225. auto ToDouble = [](uint64_t a) {
  226. return GenerateRealFromBits<double, GeneratePositiveTag, true>(a);
  227. };
  228. EXPECT_EQ(ToDouble(0x0000000000000000), 0.0);
  229. EXPECT_EQ(ToDouble(0x0000000000000000), 0.0);
  230. EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20);
  231. EXPECT_EQ(ToDouble(0x7fffffffffffffef), 0.499999999999999944489);
  232. EXPECT_EQ(ToDouble(0x8000000000000000), 0.5);
  233. // For values > 0.5, RandU64ToDouble discards up to 11 bits. (64-53).
  234. EXPECT_EQ(ToDouble(0x8000000000000001), 0.5);
  235. EXPECT_EQ(ToDouble(0x80000000000007FF), 0.5);
  236. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978);
  237. EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF));
  238. EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFF), 1.0);
  239. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF800));
  240. EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF7FF));
  241. EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00));
  242. EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFBFF));
  243. EXPECT_EQ(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFE00));
  244. EXPECT_NE(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFDFF));
  245. EXPECT_EQ(ToDouble(0x1000000000000001), 0.0625);
  246. EXPECT_EQ(ToDouble(0x2000000000000001), 0.125);
  247. EXPECT_EQ(ToDouble(0x3000000000000001), 0.1875);
  248. EXPECT_EQ(ToDouble(0x4000000000000001), 0.25);
  249. EXPECT_EQ(ToDouble(0x5000000000000001), 0.3125);
  250. EXPECT_EQ(ToDouble(0x6000000000000001), 0.375);
  251. EXPECT_EQ(ToDouble(0x7000000000000001), 0.4375);
  252. EXPECT_EQ(ToDouble(0x8000000000000001), 0.5);
  253. EXPECT_EQ(ToDouble(0x9000000000000001), 0.5625);
  254. EXPECT_EQ(ToDouble(0xa000000000000001), 0.625);
  255. EXPECT_EQ(ToDouble(0xb000000000000001), 0.6875);
  256. EXPECT_EQ(ToDouble(0xc000000000000001), 0.75);
  257. EXPECT_EQ(ToDouble(0xd000000000000001), 0.8125);
  258. EXPECT_EQ(ToDouble(0xe000000000000001), 0.875);
  259. EXPECT_EQ(ToDouble(0xf000000000000001), 0.9375);
  260. // Large powers of 2.
  261. int64_t two_to_53 = int64_t{1} << 53;
  262. EXPECT_EQ(static_cast<int64_t>(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53),
  263. two_to_53 - 1);
  264. EXPECT_NE(static_cast<int64_t>(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53 * 2),
  265. two_to_53 * 2 - 1);
  266. // For values where every bit counts, the values scale as multiples of the
  267. // input.
  268. for (int i = 0; i < 100; ++i) {
  269. EXPECT_EQ(i * ToDouble(0x0000000000000001), ToDouble(i));
  270. }
  271. // For each i: value generated from (1 << i).
  272. double exp_values[64];
  273. exp_values[63] = 0.5;
  274. for (int i = 62; i >= 0; --i) exp_values[i] = 0.5 * exp_values[i + 1];
  275. constexpr uint64_t one = 1;
  276. for (int i = 0; i < 64; ++i) {
  277. EXPECT_EQ(ToDouble(one << i), exp_values[i]);
  278. for (int j = 1; j < DBL_MANT_DIG && i - j >= 0; ++j) {
  279. EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]);
  280. EXPECT_EQ(ToDouble((one << i) + (one << (i - j))),
  281. exp_values[i] + exp_values[i - j]);
  282. }
  283. for (int j = DBL_MANT_DIG; i - j >= 0; ++j) {
  284. EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]);
  285. EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), exp_values[i]);
  286. }
  287. }
  288. }
  289. TEST(GenerateRealTest, U64ToDoubleSignedTest) {
  290. auto ToDouble = [](uint64_t a) {
  291. return GenerateRealFromBits<double, GenerateSignedTag, false>(a);
  292. };
  293. EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20);
  294. EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19);
  295. EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20);
  296. EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19);
  297. const double e_plus = ToDouble(0x0000000000000001);
  298. const double e_minus = ToDouble(0x8000000000000001);
  299. EXPECT_EQ(e_plus, 1.084202172485504434e-19);
  300. EXPECT_EQ(e_minus, -1.084202172485504434e-19);
  301. EXPECT_EQ(ToDouble(0x3fffffffffffffef), 0.499999999999999944489);
  302. EXPECT_EQ(ToDouble(0xbfffffffffffffef), -0.499999999999999944489);
  303. // For values > 0.5, RandU64ToDouble discards up to 10 bits. (63-53).
  304. EXPECT_EQ(ToDouble(0x4000000000000000), 0.5);
  305. EXPECT_EQ(ToDouble(0x4000000000000001), 0.5);
  306. EXPECT_EQ(ToDouble(0x40000000000003FF), 0.5);
  307. EXPECT_EQ(ToDouble(0xC000000000000000), -0.5);
  308. EXPECT_EQ(ToDouble(0xC000000000000001), -0.5);
  309. EXPECT_EQ(ToDouble(0xC0000000000003FF), -0.5);
  310. EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFe), 0.999999999999999888978);
  311. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999999999888978);
  312. EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF));
  313. EXPECT_LT(ToDouble(0x7FFFFFFFFFFFFFFF), 1.0);
  314. EXPECT_GT(ToDouble(0x7FFFFFFFFFFFFFFF), 0.9999999999);
  315. EXPECT_GT(ToDouble(0xFFFFFFFFFFFFFFFe), -1.0);
  316. EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999);
  317. EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFFC00));
  318. EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00));
  319. EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFF3FF));
  320. EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFF3FF));
  321. EXPECT_EQ(ToDouble(0x1000000000000001), 0.125);
  322. EXPECT_EQ(ToDouble(0x2000000000000001), 0.25);
  323. EXPECT_EQ(ToDouble(0x3000000000000001), 0.375);
  324. EXPECT_EQ(ToDouble(0x4000000000000001), 0.5);
  325. EXPECT_EQ(ToDouble(0x5000000000000001), 0.625);
  326. EXPECT_EQ(ToDouble(0x6000000000000001), 0.75);
  327. EXPECT_EQ(ToDouble(0x7000000000000001), 0.875);
  328. EXPECT_EQ(ToDouble(0x7800000000000001), 0.9375);
  329. EXPECT_EQ(ToDouble(0x7c00000000000001), 0.96875);
  330. EXPECT_EQ(ToDouble(0x7e00000000000001), 0.984375);
  331. EXPECT_EQ(ToDouble(0x7f00000000000001), 0.9921875);
  332. // 0x8000000000000000 ~= 0
  333. EXPECT_EQ(ToDouble(0x9000000000000001), -0.125);
  334. EXPECT_EQ(ToDouble(0xa000000000000001), -0.25);
  335. EXPECT_EQ(ToDouble(0xb000000000000001), -0.375);
  336. EXPECT_EQ(ToDouble(0xc000000000000001), -0.5);
  337. EXPECT_EQ(ToDouble(0xd000000000000001), -0.625);
  338. EXPECT_EQ(ToDouble(0xe000000000000001), -0.75);
  339. EXPECT_EQ(ToDouble(0xf000000000000001), -0.875);
  340. // Large powers of 2.
  341. int64_t two_to_53 = int64_t{1} << 53;
  342. EXPECT_EQ(static_cast<int64_t>(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53),
  343. two_to_53 - 1);
  344. EXPECT_EQ(static_cast<int64_t>(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53),
  345. -(two_to_53 - 1));
  346. EXPECT_NE(static_cast<int64_t>(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53 * 2),
  347. two_to_53 * 2 - 1);
  348. // For values where every bit counts, the values scale as multiples of the
  349. // input.
  350. for (int i = 1; i < 100; ++i) {
  351. EXPECT_EQ(i * e_plus, ToDouble(i)) << i;
  352. EXPECT_EQ(i * e_minus, ToDouble(0x8000000000000000 | i)) << i;
  353. }
  354. }
  355. TEST(GenerateRealTest, ExhaustiveFloat) {
  356. auto ToFloat = [](uint64_t a) {
  357. return GenerateRealFromBits<float, GeneratePositiveTag, true>(a);
  358. };
  359. // Rely on RandU64ToFloat generating values from greatest to least when
  360. // supplied with uint64_t values from greatest (0xfff...) to least (0x0).
  361. // Thus, this algorithm stores the previous value, and if the new value is at
  362. // greater than or equal to the previous value, then there is a collision in
  363. // the generation algorithm.
  364. //
  365. // Use the computation below to convert the random value into a result:
  366. // double res = a() * (1.0f - sample) + b() * sample;
  367. float last_f = 1.0, last_g = 2.0;
  368. uint64_t f_collisions = 0, g_collisions = 0;
  369. uint64_t f_unique = 0, g_unique = 0;
  370. uint64_t total = 0;
  371. auto count = [&](const float r) {
  372. total++;
  373. // `f` is mapped to the range [0, 1) (default)
  374. const float f = 0.0f * (1.0f - r) + 1.0f * r;
  375. if (f >= last_f) {
  376. f_collisions++;
  377. } else {
  378. f_unique++;
  379. last_f = f;
  380. }
  381. // `g` is mapped to the range [1, 2)
  382. const float g = 1.0f * (1.0f - r) + 2.0f * r;
  383. if (g >= last_g) {
  384. g_collisions++;
  385. } else {
  386. g_unique++;
  387. last_g = g;
  388. }
  389. };
  390. size_t limit = absl::GetFlag(FLAGS_absl_random_test_trials);
  391. // Generate all uint64_t which have unique floating point values.
  392. // Counting down from 0xFFFFFFFFFFFFFFFFu ... 0x0u
  393. uint64_t x = ~uint64_t(0);
  394. for (; x != 0 && limit > 0;) {
  395. constexpr int kDig = (64 - FLT_MANT_DIG);
  396. // Set a decrement value & the next point at which to change
  397. // the decrement value. By default these are 1, 0.
  398. uint64_t dec = 1;
  399. uint64_t chk = 0;
  400. // Adjust decrement and check value based on how many leading 0
  401. // bits are set in the current value.
  402. const int clz = absl::countl_zero(x);
  403. if (clz < kDig) {
  404. dec <<= (kDig - clz);
  405. chk = (~uint64_t(0)) >> (clz + 1);
  406. }
  407. for (; x > chk && limit > 0; x -= dec) {
  408. count(ToFloat(x));
  409. --limit;
  410. }
  411. }
  412. static_assert(FLT_MANT_DIG == 24,
  413. "The float type is expected to have a 24 bit mantissa.");
  414. if (limit != 0) {
  415. // There are between 2^28 and 2^29 unique values in the range [0, 1). For
  416. // the low values of x, there are 2^24 -1 unique values. Once x > 2^24,
  417. // there are 40 * 2^24 unique values. Thus:
  418. // (2 + 4 + 8 ... + 2^23) + 40 * 2^23
  419. EXPECT_LT(1 << 28, f_unique);
  420. EXPECT_EQ((1 << 24) + 40 * (1 << 23) - 1, f_unique);
  421. EXPECT_EQ(total, f_unique);
  422. EXPECT_EQ(0, f_collisions);
  423. // Expect at least 2^23 unique values for the range [1, 2)
  424. EXPECT_LE(1 << 23, g_unique);
  425. EXPECT_EQ(total - g_unique, g_collisions);
  426. }
  427. }
  428. } // namespace