@sentryware/s2-node 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/.circleci/config.yml +45 -0
  2. package/.dockerignore +1 -0
  3. package/.gitmodules +3 -0
  4. package/CHANGELOG.md +33 -0
  5. package/LICENSE +201 -0
  6. package/README.md +147 -0
  7. package/binding.gyp +170 -0
  8. package/docker/Dockerfile.node20.test +8 -0
  9. package/docker/Dockerfile.node22.test +8 -0
  10. package/docker/Dockerfile.node24.test +8 -0
  11. package/index.d.ts +117 -0
  12. package/index.js +6 -0
  13. package/jest.config.js +184 -0
  14. package/package.json +43 -0
  15. package/publish-linux.sh +18 -0
  16. package/publish-osx.sh +19 -0
  17. package/src/builder.cc +84 -0
  18. package/src/builder.h +29 -0
  19. package/src/cell.cc +71 -0
  20. package/src/cell.h +26 -0
  21. package/src/cell_id.cc +210 -0
  22. package/src/cell_id.h +44 -0
  23. package/src/cell_union.cc +237 -0
  24. package/src/cell_union.h +34 -0
  25. package/src/earth.cc +185 -0
  26. package/src/earth.h +33 -0
  27. package/src/latlng.cc +132 -0
  28. package/src/latlng.h +28 -0
  29. package/src/loop.cc +51 -0
  30. package/src/loop.h +21 -0
  31. package/src/point.cc +69 -0
  32. package/src/point.h +23 -0
  33. package/src/polygon.cc +36 -0
  34. package/src/polygon.h +20 -0
  35. package/src/polyline.cc +186 -0
  36. package/src/polyline.h +34 -0
  37. package/src/region_coverer.cc +450 -0
  38. package/src/region_coverer.h +56 -0
  39. package/src/s2.cc +27 -0
  40. package/test/Cell.test.js +37 -0
  41. package/test/CellId.test.js +135 -0
  42. package/test/CellUnion.test.js +150 -0
  43. package/test/Earth.test.js +62 -0
  44. package/test/LatLng.test.js +45 -0
  45. package/test/Point.test.js +14 -0
  46. package/test/Polyline.test.js +78 -0
  47. package/test/RegionCoverer.test.js +301 -0
  48. package/test.sh +16 -0
  49. package/third_party/s2geometry/.travis.yml +163 -0
  50. package/third_party/s2geometry/AUTHORS +13 -0
  51. package/third_party/s2geometry/CONTRIBUTING.md +65 -0
  52. package/third_party/s2geometry/CONTRIBUTORS +30 -0
  53. package/third_party/s2geometry/LICENSE +202 -0
  54. package/third_party/s2geometry/NOTICE +5 -0
  55. package/third_party/s2geometry/README.md +127 -0
  56. package/third_party/s2geometry/doc/examples/point_index.cc +44 -0
  57. package/third_party/s2geometry/doc/examples/term_index.cc +99 -0
  58. package/third_party/s2geometry/doc/examples/term_index.py +101 -0
  59. package/third_party/s2geometry/src/python/coder.i +125 -0
  60. package/third_party/s2geometry/src/python/pywraps2_test.py +786 -0
  61. package/third_party/s2geometry/src/python/s2.i +37 -0
  62. package/third_party/s2geometry/src/python/s2_common.i +756 -0
  63. package/third_party/s2geometry/src/s2/_fp_contract_off.h +60 -0
  64. package/third_party/s2geometry/src/s2/base/casts.h +318 -0
  65. package/third_party/s2geometry/src/s2/base/commandlineflags.h +67 -0
  66. package/third_party/s2geometry/src/s2/base/integral_types.h +31 -0
  67. package/third_party/s2geometry/src/s2/base/log_severity.h +40 -0
  68. package/third_party/s2geometry/src/s2/base/logging.h +173 -0
  69. package/third_party/s2geometry/src/s2/base/mutex.h +61 -0
  70. package/third_party/s2geometry/src/s2/base/port.h +999 -0
  71. package/third_party/s2geometry/src/s2/base/spinlock.h +60 -0
  72. package/third_party/s2geometry/src/s2/base/stringprintf.cc +107 -0
  73. package/third_party/s2geometry/src/s2/base/stringprintf.h +53 -0
  74. package/third_party/s2geometry/src/s2/base/strtoint.cc +65 -0
  75. package/third_party/s2geometry/src/s2/base/strtoint.h +106 -0
  76. package/third_party/s2geometry/src/s2/base/timer.h +50 -0
  77. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.cc +164 -0
  78. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector.h +110 -0
  79. package/third_party/s2geometry/src/s2/encoded_s2cell_id_vector_test.cc +232 -0
  80. package/third_party/s2geometry/src/s2/encoded_s2point_vector.cc +838 -0
  81. package/third_party/s2geometry/src/s2/encoded_s2point_vector.h +140 -0
  82. package/third_party/s2geometry/src/s2/encoded_s2point_vector_test.cc +344 -0
  83. package/third_party/s2geometry/src/s2/encoded_s2shape_index.cc +181 -0
  84. package/third_party/s2geometry/src/s2/encoded_s2shape_index.h +276 -0
  85. package/third_party/s2geometry/src/s2/encoded_s2shape_index_test.cc +244 -0
  86. package/third_party/s2geometry/src/s2/encoded_string_vector.cc +66 -0
  87. package/third_party/s2geometry/src/s2/encoded_string_vector.h +164 -0
  88. package/third_party/s2geometry/src/s2/encoded_string_vector_test.cc +69 -0
  89. package/third_party/s2geometry/src/s2/encoded_uint_vector.h +299 -0
  90. package/third_party/s2geometry/src/s2/encoded_uint_vector_test.cc +124 -0
  91. package/third_party/s2geometry/src/s2/id_set_lexicon.cc +81 -0
  92. package/third_party/s2geometry/src/s2/id_set_lexicon.h +199 -0
  93. package/third_party/s2geometry/src/s2/id_set_lexicon_test.cc +70 -0
  94. package/third_party/s2geometry/src/s2/mutable_s2shape_index.cc +1585 -0
  95. package/third_party/s2geometry/src/s2/mutable_s2shape_index.h +600 -0
  96. package/third_party/s2geometry/src/s2/mutable_s2shape_index_test.cc +589 -0
  97. package/third_party/s2geometry/src/s2/r1interval.h +220 -0
  98. package/third_party/s2geometry/src/s2/r1interval_test.cc +185 -0
  99. package/third_party/s2geometry/src/s2/r2.h +26 -0
  100. package/third_party/s2geometry/src/s2/r2rect.cc +93 -0
  101. package/third_party/s2geometry/src/s2/r2rect.h +234 -0
  102. package/third_party/s2geometry/src/s2/r2rect_test.cc +228 -0
  103. package/third_party/s2geometry/src/s2/s1angle.cc +54 -0
  104. package/third_party/s2geometry/src/s2/s1angle.h +336 -0
  105. package/third_party/s2geometry/src/s2/s1angle_test.cc +185 -0
  106. package/third_party/s2geometry/src/s2/s1chord_angle.cc +159 -0
  107. package/third_party/s2geometry/src/s2/s1chord_angle.h +369 -0
  108. package/third_party/s2geometry/src/s2/s1chord_angle_test.cc +207 -0
  109. package/third_party/s2geometry/src/s2/s1interval.cc +296 -0
  110. package/third_party/s2geometry/src/s2/s1interval.h +266 -0
  111. package/third_party/s2geometry/src/s2/s1interval_test.cc +469 -0
  112. package/third_party/s2geometry/src/s2/s2boolean_operation.cc +2391 -0
  113. package/third_party/s2geometry/src/s2/s2boolean_operation.h +501 -0
  114. package/third_party/s2geometry/src/s2/s2boolean_operation_test.cc +1400 -0
  115. package/third_party/s2geometry/src/s2/s2builder.cc +1828 -0
  116. package/third_party/s2geometry/src/s2/s2builder.h +1057 -0
  117. package/third_party/s2geometry/src/s2/s2builder_graph.cc +1084 -0
  118. package/third_party/s2geometry/src/s2/s2builder_graph.h +799 -0
  119. package/third_party/s2geometry/src/s2/s2builder_graph_test.cc +462 -0
  120. package/third_party/s2geometry/src/s2/s2builder_layer.h +50 -0
  121. package/third_party/s2geometry/src/s2/s2builder_test.cc +1329 -0
  122. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.cc +313 -0
  123. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer.h +221 -0
  124. package/third_party/s2geometry/src/s2/s2builderutil_closed_set_normalizer_test.cc +261 -0
  125. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.cc +392 -0
  126. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies.h +86 -0
  127. package/third_party/s2geometry/src/s2/s2builderutil_find_polygon_degeneracies_test.cc +182 -0
  128. package/third_party/s2geometry/src/s2/s2builderutil_graph_shape.h +57 -0
  129. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.cc +212 -0
  130. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer.h +218 -0
  131. package/third_party/s2geometry/src/s2/s2builderutil_lax_polygon_layer_test.cc +367 -0
  132. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.cc +74 -0
  133. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer.h +122 -0
  134. package/third_party/s2geometry/src/s2/s2builderutil_s2point_vector_layer_test.cc +167 -0
  135. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.cc +191 -0
  136. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer.h +211 -0
  137. package/third_party/s2geometry/src/s2/s2builderutil_s2polygon_layer_test.cc +312 -0
  138. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.cc +105 -0
  139. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer.h +174 -0
  140. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_layer_test.cc +220 -0
  141. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.cc +98 -0
  142. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer.h +292 -0
  143. package/third_party/s2geometry/src/s2/s2builderutil_s2polyline_vector_layer_test.cc +233 -0
  144. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.cc +354 -0
  145. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions.h +239 -0
  146. package/third_party/s2geometry/src/s2/s2builderutil_snap_functions_test.cc +716 -0
  147. package/third_party/s2geometry/src/s2/s2builderutil_testing.cc +37 -0
  148. package/third_party/s2geometry/src/s2/s2builderutil_testing.h +100 -0
  149. package/third_party/s2geometry/src/s2/s2builderutil_testing_test.cc +85 -0
  150. package/third_party/s2geometry/src/s2/s2cap.cc +347 -0
  151. package/third_party/s2geometry/src/s2/s2cap.h +286 -0
  152. package/third_party/s2geometry/src/s2/s2cap_test.cc +379 -0
  153. package/third_party/s2geometry/src/s2/s2cell.cc +552 -0
  154. package/third_party/s2geometry/src/s2/s2cell.h +249 -0
  155. package/third_party/s2geometry/src/s2/s2cell_id.cc +619 -0
  156. package/third_party/s2geometry/src/s2/s2cell_id.h +705 -0
  157. package/third_party/s2geometry/src/s2/s2cell_id_test.cc +633 -0
  158. package/third_party/s2geometry/src/s2/s2cell_index.cc +149 -0
  159. package/third_party/s2geometry/src/s2/s2cell_index.h +660 -0
  160. package/third_party/s2geometry/src/s2/s2cell_index_test.cc +411 -0
  161. package/third_party/s2geometry/src/s2/s2cell_test.cc +687 -0
  162. package/third_party/s2geometry/src/s2/s2cell_union.cc +515 -0
  163. package/third_party/s2geometry/src/s2/s2cell_union.h +399 -0
  164. package/third_party/s2geometry/src/s2/s2cell_union_test.cc +598 -0
  165. package/third_party/s2geometry/src/s2/s2centroids.cc +84 -0
  166. package/third_party/s2geometry/src/s2/s2centroids.h +87 -0
  167. package/third_party/s2geometry/src/s2/s2centroids_test.cc +82 -0
  168. package/third_party/s2geometry/src/s2/s2closest_cell_query.cc +123 -0
  169. package/third_party/s2geometry/src/s2/s2closest_cell_query.h +385 -0
  170. package/third_party/s2geometry/src/s2/s2closest_cell_query_base.h +841 -0
  171. package/third_party/s2geometry/src/s2/s2closest_cell_query_base_test.cc +63 -0
  172. package/third_party/s2geometry/src/s2/s2closest_cell_query_test.cc +412 -0
  173. package/third_party/s2geometry/src/s2/s2closest_edge_query.cc +106 -0
  174. package/third_party/s2geometry/src/s2/s2closest_edge_query.h +421 -0
  175. package/third_party/s2geometry/src/s2/s2closest_edge_query_base.h +946 -0
  176. package/third_party/s2geometry/src/s2/s2closest_edge_query_base_test.cc +59 -0
  177. package/third_party/s2geometry/src/s2/s2closest_edge_query_test.cc +505 -0
  178. package/third_party/s2geometry/src/s2/s2closest_edge_query_testing.h +91 -0
  179. package/third_party/s2geometry/src/s2/s2closest_point_query.cc +66 -0
  180. package/third_party/s2geometry/src/s2/s2closest_point_query.h +465 -0
  181. package/third_party/s2geometry/src/s2/s2closest_point_query_base.h +767 -0
  182. package/third_party/s2geometry/src/s2/s2closest_point_query_base_test.cc +63 -0
  183. package/third_party/s2geometry/src/s2/s2closest_point_query_test.cc +312 -0
  184. package/third_party/s2geometry/src/s2/s2contains_point_query.h +328 -0
  185. package/third_party/s2geometry/src/s2/s2contains_point_query_test.cc +159 -0
  186. package/third_party/s2geometry/src/s2/s2contains_vertex_query.cc +39 -0
  187. package/third_party/s2geometry/src/s2/s2contains_vertex_query.h +66 -0
  188. package/third_party/s2geometry/src/s2/s2contains_vertex_query_test.cc +67 -0
  189. package/third_party/s2geometry/src/s2/s2convex_hull_query.cc +198 -0
  190. package/third_party/s2geometry/src/s2/s2convex_hull_query.h +110 -0
  191. package/third_party/s2geometry/src/s2/s2convex_hull_query_test.cc +208 -0
  192. package/third_party/s2geometry/src/s2/s2coords.cc +146 -0
  193. package/third_party/s2geometry/src/s2/s2coords.h +459 -0
  194. package/third_party/s2geometry/src/s2/s2coords_internal.h +71 -0
  195. package/third_party/s2geometry/src/s2/s2coords_test.cc +218 -0
  196. package/third_party/s2geometry/src/s2/s2crossing_edge_query.cc +380 -0
  197. package/third_party/s2geometry/src/s2/s2crossing_edge_query.h +220 -0
  198. package/third_party/s2geometry/src/s2/s2crossing_edge_query_test.cc +382 -0
  199. package/third_party/s2geometry/src/s2/s2debug.cc +23 -0
  200. package/third_party/s2geometry/src/s2/s2debug.h +69 -0
  201. package/third_party/s2geometry/src/s2/s2distance_target.h +165 -0
  202. package/third_party/s2geometry/src/s2/s2earth.cc +52 -0
  203. package/third_party/s2geometry/src/s2/s2earth.h +268 -0
  204. package/third_party/s2geometry/src/s2/s2earth_test.cc +146 -0
  205. package/third_party/s2geometry/src/s2/s2edge_clipping.cc +462 -0
  206. package/third_party/s2geometry/src/s2/s2edge_clipping.h +183 -0
  207. package/third_party/s2geometry/src/s2/s2edge_clipping_test.cc +335 -0
  208. package/third_party/s2geometry/src/s2/s2edge_crosser.cc +85 -0
  209. package/third_party/s2geometry/src/s2/s2edge_crosser.h +343 -0
  210. package/third_party/s2geometry/src/s2/s2edge_crosser_test.cc +264 -0
  211. package/third_party/s2geometry/src/s2/s2edge_crossings.cc +515 -0
  212. package/third_party/s2geometry/src/s2/s2edge_crossings.h +138 -0
  213. package/third_party/s2geometry/src/s2/s2edge_crossings_internal.h +59 -0
  214. package/third_party/s2geometry/src/s2/s2edge_crossings_test.cc +246 -0
  215. package/third_party/s2geometry/src/s2/s2edge_distances.cc +419 -0
  216. package/third_party/s2geometry/src/s2/s2edge_distances.h +192 -0
  217. package/third_party/s2geometry/src/s2/s2edge_distances_test.cc +539 -0
  218. package/third_party/s2geometry/src/s2/s2edge_tessellator.cc +276 -0
  219. package/third_party/s2geometry/src/s2/s2edge_tessellator.h +101 -0
  220. package/third_party/s2geometry/src/s2/s2edge_tessellator_test.cc +492 -0
  221. package/third_party/s2geometry/src/s2/s2edge_vector_shape.h +85 -0
  222. package/third_party/s2geometry/src/s2/s2edge_vector_shape_test.cc +66 -0
  223. package/third_party/s2geometry/src/s2/s2error.cc +29 -0
  224. package/third_party/s2geometry/src/s2/s2error.h +147 -0
  225. package/third_party/s2geometry/src/s2/s2error_test.cc +31 -0
  226. package/third_party/s2geometry/src/s2/s2furthest_edge_query.cc +117 -0
  227. package/third_party/s2geometry/src/s2/s2furthest_edge_query.h +439 -0
  228. package/third_party/s2geometry/src/s2/s2furthest_edge_query_test.cc +487 -0
  229. package/third_party/s2geometry/src/s2/s2latlng.cc +90 -0
  230. package/third_party/s2geometry/src/s2/s2latlng.h +234 -0
  231. package/third_party/s2geometry/src/s2/s2latlng_rect.cc +727 -0
  232. package/third_party/s2geometry/src/s2/s2latlng_rect.h +434 -0
  233. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.cc +344 -0
  234. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder.h +89 -0
  235. package/third_party/s2geometry/src/s2/s2latlng_rect_bounder_test.cc +306 -0
  236. package/third_party/s2geometry/src/s2/s2latlng_rect_test.cc +1030 -0
  237. package/third_party/s2geometry/src/s2/s2latlng_test.cc +165 -0
  238. package/third_party/s2geometry/src/s2/s2lax_loop_shape.cc +104 -0
  239. package/third_party/s2geometry/src/s2/s2lax_loop_shape.h +153 -0
  240. package/third_party/s2geometry/src/s2/s2lax_loop_shape_test.cc +101 -0
  241. package/third_party/s2geometry/src/s2/s2lax_polygon_shape.cc +348 -0
  242. package/third_party/s2geometry/src/s2/s2lax_polygon_shape.h +183 -0
  243. package/third_party/s2geometry/src/s2/s2lax_polygon_shape_test.cc +234 -0
  244. package/third_party/s2geometry/src/s2/s2lax_polyline_shape.cc +118 -0
  245. package/third_party/s2geometry/src/s2/s2lax_polyline_shape.h +124 -0
  246. package/third_party/s2geometry/src/s2/s2lax_polyline_shape_test.cc +62 -0
  247. package/third_party/s2geometry/src/s2/s2loop.cc +1509 -0
  248. package/third_party/s2geometry/src/s2/s2loop.h +711 -0
  249. package/third_party/s2geometry/src/s2/s2loop_measures.cc +313 -0
  250. package/third_party/s2geometry/src/s2/s2loop_measures.h +280 -0
  251. package/third_party/s2geometry/src/s2/s2loop_measures_test.cc +367 -0
  252. package/third_party/s2geometry/src/s2/s2loop_test.cc +1371 -0
  253. package/third_party/s2geometry/src/s2/s2max_distance_targets.cc +265 -0
  254. package/third_party/s2geometry/src/s2/s2max_distance_targets.h +241 -0
  255. package/third_party/s2geometry/src/s2/s2max_distance_targets_test.cc +367 -0
  256. package/third_party/s2geometry/src/s2/s2measures.cc +128 -0
  257. package/third_party/s2geometry/src/s2/s2measures.h +78 -0
  258. package/third_party/s2geometry/src/s2/s2measures_test.cc +135 -0
  259. package/third_party/s2geometry/src/s2/s2metrics.cc +122 -0
  260. package/third_party/s2geometry/src/s2/s2metrics.h +199 -0
  261. package/third_party/s2geometry/src/s2/s2metrics_test.cc +127 -0
  262. package/third_party/s2geometry/src/s2/s2min_distance_targets.cc +295 -0
  263. package/third_party/s2geometry/src/s2/s2min_distance_targets.h +273 -0
  264. package/third_party/s2geometry/src/s2/s2min_distance_targets_test.cc +239 -0
  265. package/third_party/s2geometry/src/s2/s2padded_cell.cc +162 -0
  266. package/third_party/s2geometry/src/s2/s2padded_cell.h +108 -0
  267. package/third_party/s2geometry/src/s2/s2padded_cell_test.cc +138 -0
  268. package/third_party/s2geometry/src/s2/s2point.h +38 -0
  269. package/third_party/s2geometry/src/s2/s2point_compression.cc +388 -0
  270. package/third_party/s2geometry/src/s2/s2point_compression.h +78 -0
  271. package/third_party/s2geometry/src/s2/s2point_compression_test.cc +305 -0
  272. package/third_party/s2geometry/src/s2/s2point_index.h +345 -0
  273. package/third_party/s2geometry/src/s2/s2point_index_test.cc +147 -0
  274. package/third_party/s2geometry/src/s2/s2point_region.cc +72 -0
  275. package/third_party/s2geometry/src/s2/s2point_region.h +76 -0
  276. package/third_party/s2geometry/src/s2/s2point_region_test.cc +100 -0
  277. package/third_party/s2geometry/src/s2/s2point_span.h +57 -0
  278. package/third_party/s2geometry/src/s2/s2point_test.cc +47 -0
  279. package/third_party/s2geometry/src/s2/s2point_vector_shape.h +127 -0
  280. package/third_party/s2geometry/src/s2/s2point_vector_shape_test.cc +59 -0
  281. package/third_party/s2geometry/src/s2/s2pointutil.cc +131 -0
  282. package/third_party/s2geometry/src/s2/s2pointutil.h +138 -0
  283. package/third_party/s2geometry/src/s2/s2pointutil_test.cc +157 -0
  284. package/third_party/s2geometry/src/s2/s2polygon.cc +1569 -0
  285. package/third_party/s2geometry/src/s2/s2polygon.h +934 -0
  286. package/third_party/s2geometry/src/s2/s2polygon_test.cc +3025 -0
  287. package/third_party/s2geometry/src/s2/s2polyline.cc +645 -0
  288. package/third_party/s2geometry/src/s2/s2polyline.h +379 -0
  289. package/third_party/s2geometry/src/s2/s2polyline_alignment.cc +414 -0
  290. package/third_party/s2geometry/src/s2/s2polyline_alignment.h +245 -0
  291. package/third_party/s2geometry/src/s2/s2polyline_alignment_internal.h +158 -0
  292. package/third_party/s2geometry/src/s2/s2polyline_alignment_test.cc +610 -0
  293. package/third_party/s2geometry/src/s2/s2polyline_measures.cc +42 -0
  294. package/third_party/s2geometry/src/s2/s2polyline_measures.h +53 -0
  295. package/third_party/s2geometry/src/s2/s2polyline_measures_test.cc +57 -0
  296. package/third_party/s2geometry/src/s2/s2polyline_simplifier.cc +187 -0
  297. package/third_party/s2geometry/src/s2/s2polyline_simplifier.h +109 -0
  298. package/third_party/s2geometry/src/s2/s2polyline_simplifier_test.cc +165 -0
  299. package/third_party/s2geometry/src/s2/s2polyline_test.cc +554 -0
  300. package/third_party/s2geometry/src/s2/s2predicates.cc +1486 -0
  301. package/third_party/s2geometry/src/s2/s2predicates.h +282 -0
  302. package/third_party/s2geometry/src/s2/s2predicates_internal.h +135 -0
  303. package/third_party/s2geometry/src/s2/s2predicates_test.cc +1427 -0
  304. package/third_party/s2geometry/src/s2/s2projections.cc +109 -0
  305. package/third_party/s2geometry/src/s2/s2projections.h +161 -0
  306. package/third_party/s2geometry/src/s2/s2projections_test.cc +78 -0
  307. package/third_party/s2geometry/src/s2/s2r2rect.cc +88 -0
  308. package/third_party/s2geometry/src/s2/s2r2rect.h +292 -0
  309. package/third_party/s2geometry/src/s2/s2r2rect_test.cc +312 -0
  310. package/third_party/s2geometry/src/s2/s2region.cc +26 -0
  311. package/third_party/s2geometry/src/s2/s2region.h +142 -0
  312. package/third_party/s2geometry/src/s2/s2region_coverer.cc +514 -0
  313. package/third_party/s2geometry/src/s2/s2region_coverer.h +356 -0
  314. package/third_party/s2geometry/src/s2/s2region_coverer_test.cc +509 -0
  315. package/third_party/s2geometry/src/s2/s2region_intersection.cc +84 -0
  316. package/third_party/s2geometry/src/s2/s2region_intersection.h +79 -0
  317. package/third_party/s2geometry/src/s2/s2region_term_indexer.cc +270 -0
  318. package/third_party/s2geometry/src/s2/s2region_term_indexer.h +299 -0
  319. package/third_party/s2geometry/src/s2/s2region_term_indexer_test.cc +209 -0
  320. package/third_party/s2geometry/src/s2/s2region_test.cc +370 -0
  321. package/third_party/s2geometry/src/s2/s2region_union.cc +90 -0
  322. package/third_party/s2geometry/src/s2/s2region_union.h +83 -0
  323. package/third_party/s2geometry/src/s2/s2region_union_test.cc +89 -0
  324. package/third_party/s2geometry/src/s2/s2shape.h +283 -0
  325. package/third_party/s2geometry/src/s2/s2shape_index.cc +321 -0
  326. package/third_party/s2geometry/src/s2/s2shape_index.h +781 -0
  327. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.cc +113 -0
  328. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region.h +135 -0
  329. package/third_party/s2geometry/src/s2/s2shape_index_buffered_region_test.cc +162 -0
  330. package/third_party/s2geometry/src/s2/s2shape_index_measures.cc +92 -0
  331. package/third_party/s2geometry/src/s2/s2shape_index_measures.h +100 -0
  332. package/third_party/s2geometry/src/s2/s2shape_index_measures_test.cc +136 -0
  333. package/third_party/s2geometry/src/s2/s2shape_index_region.h +350 -0
  334. package/third_party/s2geometry/src/s2/s2shape_index_region_test.cc +161 -0
  335. package/third_party/s2geometry/src/s2/s2shape_index_test.cc +24 -0
  336. package/third_party/s2geometry/src/s2/s2shape_measures.cc +138 -0
  337. package/third_party/s2geometry/src/s2/s2shape_measures.h +95 -0
  338. package/third_party/s2geometry/src/s2/s2shape_measures_test.cc +139 -0
  339. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.cc +120 -0
  340. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries.h +66 -0
  341. package/third_party/s2geometry/src/s2/s2shapeutil_build_polygon_boundaries_test.cc +170 -0
  342. package/third_party/s2geometry/src/s2/s2shapeutil_coding.cc +253 -0
  343. package/third_party/s2geometry/src/s2/s2shapeutil_coding.h +283 -0
  344. package/third_party/s2geometry/src/s2/s2shapeutil_coding_test.cc +54 -0
  345. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.cc +40 -0
  346. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force.h +41 -0
  347. package/third_party/s2geometry/src/s2/s2shapeutil_contains_brute_force_test.cc +55 -0
  348. package/third_party/s2geometry/src/s2/s2shapeutil_count_edges.h +57 -0
  349. package/third_party/s2geometry/src/s2/s2shapeutil_count_edges_test.cc +43 -0
  350. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.cc +45 -0
  351. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator.h +72 -0
  352. package/third_party/s2geometry/src/s2/s2shapeutil_edge_iterator_test.cc +116 -0
  353. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.cc +107 -0
  354. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point.h +48 -0
  355. package/third_party/s2geometry/src/s2/s2shapeutil_get_reference_point_test.cc +104 -0
  356. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.cc +58 -0
  357. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator.h +65 -0
  358. package/third_party/s2geometry/src/s2/s2shapeutil_range_iterator_test.cc +61 -0
  359. package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge.h +58 -0
  360. package/third_party/s2geometry/src/s2/s2shapeutil_shape_edge_id.h +97 -0
  361. package/third_party/s2geometry/src/s2/s2shapeutil_testing.cc +104 -0
  362. package/third_party/s2geometry/src/s2/s2shapeutil_testing.h +36 -0
  363. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.cc +440 -0
  364. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs.h +72 -0
  365. package/third_party/s2geometry/src/s2/s2shapeutil_visit_crossing_edge_pairs_test.cc +184 -0
  366. package/third_party/s2geometry/src/s2/s2testing.cc +464 -0
  367. package/third_party/s2geometry/src/s2/s2testing.h +385 -0
  368. package/third_party/s2geometry/src/s2/s2testing_test.cc +166 -0
  369. package/third_party/s2geometry/src/s2/s2text_format.cc +506 -0
  370. package/third_party/s2geometry/src/s2/s2text_format.h +289 -0
  371. package/third_party/s2geometry/src/s2/s2text_format_test.cc +417 -0
  372. package/third_party/s2geometry/src/s2/s2wedge_relations.cc +80 -0
  373. package/third_party/s2geometry/src/s2/s2wedge_relations.h +64 -0
  374. package/third_party/s2geometry/src/s2/s2wedge_relations_test.cc +89 -0
  375. package/third_party/s2geometry/src/s2/sequence_lexicon.h +296 -0
  376. package/third_party/s2geometry/src/s2/sequence_lexicon_test.cc +113 -0
  377. package/third_party/s2geometry/src/s2/strings/ostringstream.cc +35 -0
  378. package/third_party/s2geometry/src/s2/strings/ostringstream.h +105 -0
  379. package/third_party/s2geometry/src/s2/strings/serialize.cc +46 -0
  380. package/third_party/s2geometry/src/s2/strings/serialize.h +40 -0
  381. package/third_party/s2geometry/src/s2/third_party/absl/algorithm/algorithm.h +187 -0
  382. package/third_party/s2geometry/src/s2/third_party/absl/base/attributes.h +666 -0
  383. package/third_party/s2geometry/src/s2/third_party/absl/base/casts.h +189 -0
  384. package/third_party/s2geometry/src/s2/third_party/absl/base/config.h +462 -0
  385. package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.cc +129 -0
  386. package/third_party/s2geometry/src/s2/third_party/absl/base/dynamic_annotations.h +394 -0
  387. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/atomic_hook.h +168 -0
  388. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/identity.h +33 -0
  389. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/inline_variable.h +117 -0
  390. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/invoke.h +188 -0
  391. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.cc +254 -0
  392. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/raw_logging.h +205 -0
  393. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.cc +106 -0
  394. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/throw_delegate.h +71 -0
  395. package/third_party/s2geometry/src/s2/third_party/absl/base/internal/unaligned_access.h +322 -0
  396. package/third_party/s2geometry/src/s2/third_party/absl/base/log_severity.h +77 -0
  397. package/third_party/s2geometry/src/s2/third_party/absl/base/macros.h +236 -0
  398. package/third_party/s2geometry/src/s2/third_party/absl/base/optimization.h +177 -0
  399. package/third_party/s2geometry/src/s2/third_party/absl/base/policy_checks.h +124 -0
  400. package/third_party/s2geometry/src/s2/third_party/absl/base/port.h +97 -0
  401. package/third_party/s2geometry/src/s2/third_party/absl/base/thread_annotations.h +277 -0
  402. package/third_party/s2geometry/src/s2/third_party/absl/container/fixed_array.h +523 -0
  403. package/third_party/s2geometry/src/s2/third_party/absl/container/inlined_vector.h +1453 -0
  404. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/compressed_tuple.h +191 -0
  405. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/container_memory.h +424 -0
  406. package/third_party/s2geometry/src/s2/third_party/absl/container/internal/layout.h +739 -0
  407. package/third_party/s2geometry/src/s2/third_party/absl/memory/memory.h +755 -0
  408. package/third_party/s2geometry/src/s2/third_party/absl/meta/type_traits.h +436 -0
  409. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.cc +232 -0
  410. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128.h +656 -0
  411. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_have_intrinsic.inc +3 -0
  412. package/third_party/s2geometry/src/s2/third_party/absl/numeric/int128_no_intrinsic.inc +3 -0
  413. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.cc +198 -0
  414. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii.h +239 -0
  415. package/third_party/s2geometry/src/s2/third_party/absl/strings/ascii_ctype.h +66 -0
  416. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/bits.h +53 -0
  417. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.cc +110 -0
  418. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/memutil.h +146 -0
  419. package/third_party/s2geometry/src/s2/third_party/absl/strings/internal/resize_uninitialized.h +72 -0
  420. package/third_party/s2geometry/src/s2/third_party/absl/strings/match.cc +38 -0
  421. package/third_party/s2geometry/src/s2/third_party/absl/strings/match.h +89 -0
  422. package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.cc +909 -0
  423. package/third_party/s2geometry/src/s2/third_party/absl/strings/numbers.h +187 -0
  424. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.cc +240 -0
  425. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_cat.h +398 -0
  426. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_join.h +22 -0
  427. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.cc +47 -0
  428. package/third_party/s2geometry/src/s2/third_party/absl/strings/str_split.h +43 -0
  429. package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.cc +245 -0
  430. package/third_party/s2geometry/src/s2/third_party/absl/strings/string_view.h +602 -0
  431. package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.cc +42 -0
  432. package/third_party/s2geometry/src/s2/third_party/absl/strings/strip.h +130 -0
  433. package/third_party/s2geometry/src/s2/third_party/absl/types/span.h +793 -0
  434. package/third_party/s2geometry/src/s2/third_party/absl/utility/utility.h +299 -0
  435. package/third_party/s2geometry/src/s2/util/bits/bit-interleave.cc +274 -0
  436. package/third_party/s2geometry/src/s2/util/bits/bit-interleave.h +53 -0
  437. package/third_party/s2geometry/src/s2/util/bits/bits.cc +155 -0
  438. package/third_party/s2geometry/src/s2/util/bits/bits.h +745 -0
  439. package/third_party/s2geometry/src/s2/util/coding/coder.cc +83 -0
  440. package/third_party/s2geometry/src/s2/util/coding/coder.h +553 -0
  441. package/third_party/s2geometry/src/s2/util/coding/nth-derivative.h +134 -0
  442. package/third_party/s2geometry/src/s2/util/coding/transforms.h +62 -0
  443. package/third_party/s2geometry/src/s2/util/coding/varint.cc +289 -0
  444. package/third_party/s2geometry/src/s2/util/coding/varint.h +476 -0
  445. package/third_party/s2geometry/src/s2/util/endian/endian.h +859 -0
  446. package/third_party/s2geometry/src/s2/util/gtl/btree.h +2471 -0
  447. package/third_party/s2geometry/src/s2/util/gtl/btree_container.h +411 -0
  448. package/third_party/s2geometry/src/s2/util/gtl/btree_map.h +79 -0
  449. package/third_party/s2geometry/src/s2/util/gtl/btree_set.h +73 -0
  450. package/third_party/s2geometry/src/s2/util/gtl/compact_array.h +653 -0
  451. package/third_party/s2geometry/src/s2/util/gtl/container_logging.h +291 -0
  452. package/third_party/s2geometry/src/s2/util/gtl/dense_hash_set.h +358 -0
  453. package/third_party/s2geometry/src/s2/util/gtl/densehashtable.h +1493 -0
  454. package/third_party/s2geometry/src/s2/util/gtl/hashtable_common.h +253 -0
  455. package/third_party/s2geometry/src/s2/util/gtl/layout.h +28 -0
  456. package/third_party/s2geometry/src/s2/util/gtl/legacy_random_shuffle.h +77 -0
  457. package/third_party/s2geometry/src/s2/util/hash/mix.h +76 -0
  458. package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.cc +832 -0
  459. package/third_party/s2geometry/src/s2/util/math/exactfloat/exactfloat.h +646 -0
  460. package/third_party/s2geometry/src/s2/util/math/mathutil.cc +75 -0
  461. package/third_party/s2geometry/src/s2/util/math/mathutil.h +189 -0
  462. package/third_party/s2geometry/src/s2/util/math/matrix3x3.h +574 -0
  463. package/third_party/s2geometry/src/s2/util/math/vector.h +569 -0
  464. package/third_party/s2geometry/src/s2/util/math/vector3_hash.h +54 -0
  465. package/third_party/s2geometry/src/s2/util/units/length-units.cc +21 -0
  466. package/third_party/s2geometry/src/s2/util/units/length-units.h +135 -0
  467. package/third_party/s2geometry/src/s2/util/units/physical-units.h +313 -0
  468. package/third_party/s2geometry/src/s2/value_lexicon.h +234 -0
  469. package/third_party/s2geometry/src/s2/value_lexicon_test.cc +121 -0
  470. package/third_party/s2geometry/third_party/cmake/FindGFlags.cmake +48 -0
  471. package/third_party/s2geometry/third_party/cmake/FindGlog.cmake +48 -0
@@ -0,0 +1,832 @@
1
+ // Copyright 2009 Google Inc. All Rights Reserved.
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
+ // http://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
+ //
15
+
16
+ // Author: ericv@google.com (Eric Veach)
17
+
18
+ #include "s2/util/math/exactfloat/exactfloat.h"
19
+
20
+ #include <cstdio>
21
+ #include <cstdlib>
22
+ #include <cstring>
23
+ #include <algorithm>
24
+ #include <cmath>
25
+ #include <limits>
26
+
27
+ #include <openssl/bn.h>
28
+ #include <openssl/crypto.h> // for OPENSSL_free
29
+
30
+ #include "s2/base/integral_types.h"
31
+ #include "s2/base/logging.h"
32
+ #include "s2/third_party/absl/base/macros.h"
33
+ #include "s2/third_party/absl/container/fixed_array.h"
34
+
35
+ using std::max;
36
+ using std::min;
37
+
38
+ // Define storage for constants.
39
+ const int ExactFloat::kMinExp;
40
+ const int ExactFloat::kMaxExp;
41
+ const int ExactFloat::kMaxPrec;
42
+ const int32 ExactFloat::kExpNaN;
43
+ const int32 ExactFloat::kExpInfinity;
44
+ const int32 ExactFloat::kExpZero;
45
+ const int ExactFloat::kDoubleMantissaBits;
46
+
47
+ // To simplify the overflow/underflow logic, we limit the exponent and
48
+ // precision range so that (2 * bn_exp_) does not overflow an "int". We take
49
+ // advantage of this, for example, by only checking for overflow/underflow
50
+ // *after* multiplying two numbers.
51
+ static_assert(
52
+ ExactFloat::kMaxExp <= INT_MAX / 2 &&
53
+ ExactFloat::kMinExp - ExactFloat::kMaxPrec >= INT_MIN / 2,
54
+ "exactfloat exponent might overflow");
55
+
56
+ // We define a few simple extensions to the OpenSSL's BIGNUM interface.
57
+ // In some cases these depend on BIGNUM internal fields, so they might
58
+ // require tweaking if the BIGNUM implementation changes significantly.
59
+ // These are just thin wrappers for BoringSSL.
60
+
61
+ #ifdef OPENSSL_IS_BORINGSSL
62
+
63
+ inline static void BN_ext_set_uint64(BIGNUM* bn, uint64 v) {
64
+ S2_CHECK(BN_set_u64(bn, v));
65
+ }
66
+
67
+ // Return the absolute value of a BIGNUM as a 64-bit unsigned integer.
68
+ // Requires that BIGNUM fits into 64 bits.
69
+ inline static uint64 BN_ext_get_uint64(const BIGNUM* bn) {
70
+ uint64_t u64;
71
+ if (!BN_get_u64(bn, &u64)) {
72
+ S2_DCHECK(false) << "BN has " << BN_num_bits(bn) << " bits";
73
+ return 0;
74
+ }
75
+ return u64;
76
+ }
77
+
78
+ static int BN_ext_count_low_zero_bits(const BIGNUM* bn) {
79
+ return BN_count_low_zero_bits(bn);
80
+ }
81
+
82
+ #else // !defined(OPENSSL_IS_BORINGSSL)
83
+
84
+ // Set a BIGNUM to the given unsigned 64-bit value.
85
+ inline static void BN_ext_set_uint64(BIGNUM* bn, uint64 v) {
86
+ #if BN_BITS2 == 64
87
+ S2_CHECK(BN_set_word(bn, v));
88
+ #else
89
+ static_assert(BN_BITS2 == 32, "at least 32 bit openssl build needed");
90
+ S2_CHECK(BN_set_word(bn, static_cast<uint32>(v >> 32)));
91
+ S2_CHECK(BN_lshift(bn, bn, 32));
92
+ S2_CHECK(BN_add_word(bn, static_cast<uint32>(v)));
93
+ #endif
94
+ }
95
+
96
+ // Return the absolute value of a BIGNUM as a 64-bit unsigned integer.
97
+ // Requires that BIGNUM fits into 64 bits.
98
+ inline static uint64 BN_ext_get_uint64(const BIGNUM* bn) {
99
+ S2_DCHECK_LE(BN_num_bytes(bn), sizeof(uint64));
100
+ #if BN_BITS2 == 64
101
+ return BN_get_word(bn);
102
+ #else
103
+ static_assert(BN_BITS2 == 32, "at least 32 bit openssl build needed");
104
+ if (bn->top == 0) return 0;
105
+ if (bn->top == 1) return BN_get_word(bn);
106
+ S2_DCHECK_EQ(bn->top, 2);
107
+ return (static_cast<uint64>(bn->d[1]) << 32) + bn->d[0];
108
+ #endif
109
+ }
110
+
111
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
112
+
113
+ // Count the number of low-order zero bits in the given BIGNUM (ignoring its
114
+ // sign). Returns 0 if the argument is zero.
115
+ static int BN_ext_count_low_zero_bits(const BIGNUM* bn) {
116
+ int count = 0;
117
+ for (int i = 0; i < bn->top; ++i) {
118
+ BN_ULONG w = bn->d[i];
119
+ if (w == 0) {
120
+ count += 8 * sizeof(BN_ULONG);
121
+ } else {
122
+ for (; (w & 1) == 0; w >>= 1) {
123
+ ++count;
124
+ }
125
+ break;
126
+ }
127
+ }
128
+ return count;
129
+ }
130
+
131
+ #else // OPENSSL_VERSION_NUMBER >= 0x10100000L
132
+
133
+ static int BN_ext_count_low_zero_bits(const BIGNUM* bn) {
134
+ // In OpenSSL >= 1.1, BIGNUM is an opaque type, so d and top
135
+ // cannot be accessed. The bytes must be copied out at a ~25%
136
+ // performance penalty.
137
+ absl::FixedArray<unsigned char> bytes(BN_num_bytes(bn));
138
+ // "le" indicates little endian.
139
+ S2_CHECK_EQ(BN_bn2lebinpad(bn, bytes.data(), bytes.size()), bytes.size());
140
+
141
+ int count = 0;
142
+ for (unsigned char c : bytes) {
143
+ if (c == 0) {
144
+ count += 8;
145
+ } else {
146
+ for (; (c & 1) == 0; c >>= 1) {
147
+ ++count;
148
+ }
149
+ break;
150
+ }
151
+ }
152
+ return count;
153
+ }
154
+
155
+ #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L
156
+
157
+ #endif // !defined(OPENSSL_IS_BORINGSSL)
158
+
159
+ ExactFloat::ExactFloat(double v) {
160
+ sign_ = std::signbit(v) ? -1 : 1;
161
+ if (std::isnan(v)) {
162
+ set_nan();
163
+ } else if (std::isinf(v)) {
164
+ set_inf(sign_);
165
+ } else {
166
+ // The following code is much simpler than messing about with bit masks,
167
+ // has the advantage of handling denormalized numbers and zero correctly,
168
+ // and is actually quite efficient (at least compared to the rest of this
169
+ // code). "f" is a fraction in the range [0.5, 1), so if we shift it left
170
+ // by the number of mantissa bits in a double (53, including the leading
171
+ // "1") then the result is always an integer.
172
+ int exp;
173
+ double f = frexp(fabs(v), &exp);
174
+ uint64 m = static_cast<uint64>(ldexp(f, kDoubleMantissaBits));
175
+ BN_ext_set_uint64(bn_.get(), m);
176
+ bn_exp_ = exp - kDoubleMantissaBits;
177
+ Canonicalize();
178
+ }
179
+ }
180
+
181
+ ExactFloat::ExactFloat(int v) {
182
+ sign_ = (v >= 0) ? 1 : -1;
183
+ // Note that this works even for INT_MIN because the parameter type for
184
+ // BN_set_word() is unsigned.
185
+ S2_CHECK(BN_set_word(bn_.get(), abs(v)));
186
+ bn_exp_ = 0;
187
+ Canonicalize();
188
+ }
189
+
190
+ ExactFloat::ExactFloat(const ExactFloat& b)
191
+ : sign_(b.sign_),
192
+ bn_exp_(b.bn_exp_) {
193
+ BN_copy(bn_.get(), b.bn_.get());
194
+ }
195
+
196
+ ExactFloat ExactFloat::SignedZero(int sign) {
197
+ ExactFloat r;
198
+ r.set_zero(sign);
199
+ return r;
200
+ }
201
+
202
+ ExactFloat ExactFloat::Infinity(int sign) {
203
+ ExactFloat r;
204
+ r.set_inf(sign);
205
+ return r;
206
+ }
207
+
208
+ ExactFloat ExactFloat::NaN() {
209
+ ExactFloat r;
210
+ r.set_nan();
211
+ return r;
212
+ }
213
+
214
+ int ExactFloat::prec() const {
215
+ return BN_num_bits(bn_.get());
216
+ }
217
+
218
+ int ExactFloat::exp() const {
219
+ S2_DCHECK(is_normal());
220
+ return bn_exp_ + BN_num_bits(bn_.get());
221
+ }
222
+
223
+ void ExactFloat::set_zero(int sign) {
224
+ sign_ = sign;
225
+ bn_exp_ = kExpZero;
226
+ if (!BN_is_zero(bn_.get())) BN_zero(bn_.get());
227
+ }
228
+
229
+ void ExactFloat::set_inf(int sign) {
230
+ sign_ = sign;
231
+ bn_exp_ = kExpInfinity;
232
+ if (!BN_is_zero(bn_.get())) BN_zero(bn_.get());
233
+ }
234
+
235
+ void ExactFloat::set_nan() {
236
+ sign_ = 1;
237
+ bn_exp_ = kExpNaN;
238
+ if (!BN_is_zero(bn_.get())) BN_zero(bn_.get());
239
+ }
240
+
241
+ double ExactFloat::ToDouble() const {
242
+ // If the mantissa has too many bits, we need to round it.
243
+ if (prec() <= kDoubleMantissaBits) {
244
+ return ToDoubleHelper();
245
+ } else {
246
+ ExactFloat r = RoundToMaxPrec(kDoubleMantissaBits, kRoundTiesToEven);
247
+ return r.ToDoubleHelper();
248
+ }
249
+ }
250
+
251
+ double ExactFloat::ToDoubleHelper() const {
252
+ S2_DCHECK_LE(BN_num_bits(bn_.get()), kDoubleMantissaBits);
253
+ if (!is_normal()) {
254
+ if (is_zero()) return copysign(0, sign_);
255
+ if (is_inf()) {
256
+ return std::copysign(std::numeric_limits<double>::infinity(), sign_);
257
+ }
258
+ return std::copysign(std::numeric_limits<double>::quiet_NaN(), sign_);
259
+ }
260
+ uint64 d_mantissa = BN_ext_get_uint64(bn_.get());
261
+ // We rely on ldexp() to handle overflow and underflow. (It will return a
262
+ // signed zero or infinity if the result is too small or too large.)
263
+ return sign_ * ldexp(static_cast<double>(d_mantissa), bn_exp_);
264
+ }
265
+
266
+ ExactFloat ExactFloat::RoundToMaxPrec(int max_prec, RoundingMode mode) const {
267
+ // The "kRoundTiesToEven" mode requires at least 2 bits of precision
268
+ // (otherwise both adjacent representable values may be odd).
269
+ S2_DCHECK_GE(max_prec, 2);
270
+ S2_DCHECK_LE(max_prec, kMaxPrec);
271
+
272
+ // The following test also catches zero, infinity, and NaN.
273
+ int shift = prec() - max_prec;
274
+ if (shift <= 0) return *this;
275
+
276
+ // Round by removing the appropriate number of bits from the mantissa. Note
277
+ // that if the value is rounded up to a power of 2, the high-order bit
278
+ // position may increase, but in that case Canonicalize() will remove at
279
+ // least one zero bit and so the output will still have prec() <= max_prec.
280
+ return RoundToPowerOf2(bn_exp_ + shift, mode);
281
+ }
282
+
283
+ ExactFloat ExactFloat::RoundToPowerOf2(int bit_exp, RoundingMode mode) const {
284
+ S2_DCHECK_GE(bit_exp, kMinExp - kMaxPrec);
285
+ S2_DCHECK_LE(bit_exp, kMaxExp);
286
+
287
+ // If the exponent is already large enough, or the value is zero, infinity,
288
+ // or NaN, then there is nothing to do.
289
+ int shift = bit_exp - bn_exp_;
290
+ if (shift <= 0) return *this;
291
+ S2_DCHECK(is_normal());
292
+
293
+ // Convert rounding up/down to toward/away from zero, so that we don't need
294
+ // to consider the sign of the number from this point onward.
295
+ if (mode == kRoundTowardPositive) {
296
+ mode = (sign_ > 0) ? kRoundAwayFromZero : kRoundTowardZero;
297
+ } else if (mode == kRoundTowardNegative) {
298
+ mode = (sign_ > 0) ? kRoundTowardZero : kRoundAwayFromZero;
299
+ }
300
+
301
+ // Rounding consists of right-shifting the mantissa by "shift", and then
302
+ // possibly incrementing the result (depending on the rounding mode, the
303
+ // bits that were discarded, and sometimes the lowest kept bit). The
304
+ // following code figures out whether we need to increment.
305
+ ExactFloat r;
306
+ bool increment = false;
307
+ if (mode == kRoundTowardZero) {
308
+ // Never increment.
309
+ } else if (mode == kRoundTiesAwayFromZero) {
310
+ // Increment if the highest discarded bit is 1.
311
+ if (BN_is_bit_set(bn_.get(), shift - 1))
312
+ increment = true;
313
+ } else if (mode == kRoundAwayFromZero) {
314
+ // Increment unless all discarded bits are zero.
315
+ if (BN_ext_count_low_zero_bits(bn_.get()) < shift)
316
+ increment = true;
317
+ } else {
318
+ S2_DCHECK_EQ(mode, kRoundTiesToEven);
319
+ // Let "w/xyz" denote a mantissa where "w" is the lowest kept bit and
320
+ // "xyz" are the discarded bits. Then using regexp notation:
321
+ // ./0.* -> Don't increment (fraction < 1/2)
322
+ // 0/10* -> Don't increment (fraction = 1/2, kept part even)
323
+ // 1/10* -> Increment (fraction = 1/2, kept part odd)
324
+ // ./1.*1.* -> Increment (fraction > 1/2)
325
+ if (BN_is_bit_set(bn_.get(), shift - 1) &&
326
+ ((BN_is_bit_set(bn_.get(), shift) ||
327
+ BN_ext_count_low_zero_bits(bn_.get()) < shift - 1))) {
328
+ increment = true;
329
+ }
330
+ }
331
+ r.bn_exp_ = bn_exp_ + shift;
332
+ S2_CHECK(BN_rshift(r.bn_.get(), bn_.get(), shift));
333
+ if (increment) {
334
+ S2_CHECK(BN_add_word(r.bn_.get(), 1));
335
+ }
336
+ r.sign_ = sign_;
337
+ r.Canonicalize();
338
+ return r;
339
+ }
340
+
341
+ int ExactFloat::NumSignificantDigitsForPrec(int prec) {
342
+ // The simplest bound is
343
+ //
344
+ // d <= 1 + ceil(prec * log10(2))
345
+ //
346
+ // The following bound is tighter by 0.5 digits on average, but requires
347
+ // the exponent to be known as well:
348
+ //
349
+ // d <= ceil(exp * log10(2)) - floor((exp - prec) * log10(2))
350
+ //
351
+ // Since either of these bounds can be too large by 0, 1, or 2 digits, we
352
+ // stick with the simpler first bound.
353
+ return static_cast<int>(1 + ceil(prec * (M_LN2 / M_LN10)));
354
+ }
355
+
356
+ // Numbers are always formatted with at least this many significant digits.
357
+ // This prevents small integers from being formatted in exponential notation
358
+ // (e.g. 1024 formatted as 1e+03), and also avoids the confusion of having
359
+ // supposedly "high precision" numbers formatted with just 1 or 2 digits
360
+ // (e.g. 1/512 == 0.001953125 formatted as 0.002).
361
+ static const int kMinSignificantDigits = 10;
362
+
363
+ string ExactFloat::ToString() const {
364
+ int max_digits = max(kMinSignificantDigits,
365
+ NumSignificantDigitsForPrec(prec()));
366
+ return ToStringWithMaxDigits(max_digits);
367
+ }
368
+
369
+ string ExactFloat::ToStringWithMaxDigits(int max_digits) const {
370
+ S2_DCHECK_GT(max_digits, 0);
371
+ if (!is_normal()) {
372
+ if (is_nan()) return "nan";
373
+ if (is_zero()) return (sign_ < 0) ? "-0" : "0";
374
+ return (sign_ < 0) ? "-inf" : "inf";
375
+ }
376
+ string digits;
377
+ int exp10 = GetDecimalDigits(max_digits, &digits);
378
+ string str;
379
+ if (sign_ < 0) str.push_back('-');
380
+
381
+ // We use the standard '%g' formatting rules. If the exponent is less than
382
+ // -4 or greater than or equal to the requested precision (i.e., max_digits)
383
+ // then we use exponential notation.
384
+ //
385
+ // But since "exp10" is the base-10 exponent corresponding to a mantissa in
386
+ // the range [0.1, 1), whereas the '%g' rules assume a mantissa in the range
387
+ // [1.0, 10), we need to adjust these parameters by 1.
388
+ if (exp10 <= -4 || exp10 > max_digits) {
389
+ // Use exponential format.
390
+ str.push_back(digits[0]);
391
+ if (digits.size() > 1) {
392
+ str.push_back('.');
393
+ str.append(digits.begin() + 1, digits.end());
394
+ }
395
+ char exp_buf[20];
396
+ sprintf(exp_buf, "e%+02d", exp10 - 1);
397
+ str += exp_buf;
398
+ } else {
399
+ // Use fixed format. We split this into two cases depending on whether
400
+ // the integer portion is non-zero or not.
401
+ if (exp10 > 0) {
402
+ if (exp10 >= digits.size()) {
403
+ str += digits;
404
+ for (int i = exp10 - digits.size(); i > 0; --i) {
405
+ str.push_back('0');
406
+ }
407
+ } else {
408
+ str.append(digits.begin(), digits.begin() + exp10);
409
+ str.push_back('.');
410
+ str.append(digits.begin() + exp10, digits.end());
411
+ }
412
+ } else {
413
+ str += "0.";
414
+ for (int i = exp10; i < 0; ++i) {
415
+ str.push_back('0');
416
+ }
417
+ str += digits;
418
+ }
419
+ }
420
+ return str;
421
+ }
422
+
423
+ // Increment an unsigned integer represented as a string of ASCII digits.
424
+ static void IncrementDecimalDigits(string* digits) {
425
+ string::iterator pos = digits->end();
426
+ while (--pos >= digits->begin()) {
427
+ if (*pos < '9') { ++*pos; return; }
428
+ *pos = '0';
429
+ }
430
+ digits->insert(0, "1");
431
+ }
432
+
433
+ int ExactFloat::GetDecimalDigits(int max_digits, string* digits) const {
434
+ S2_DCHECK(is_normal());
435
+ // Convert the value to the form (bn * (10 ** bn_exp10)) where "bn" is a
436
+ // positive integer (BIGNUM).
437
+ BIGNUM* bn = BN_new();
438
+ int bn_exp10;
439
+ if (bn_exp_ >= 0) {
440
+ // The easy case: bn = bn_ * (2 ** bn_exp_)), bn_exp10 = 0.
441
+ S2_CHECK(BN_lshift(bn, bn_.get(), bn_exp_));
442
+ bn_exp10 = 0;
443
+ } else {
444
+ // Set bn = bn_ * (5 ** -bn_exp_) and bn_exp10 = bn_exp_. This is
445
+ // equivalent to the original value of (bn_ * (2 ** bn_exp_)).
446
+ BIGNUM* power = BN_new();
447
+ S2_CHECK(BN_set_word(power, -bn_exp_));
448
+ S2_CHECK(BN_set_word(bn, 5));
449
+ BN_CTX* ctx = BN_CTX_new();
450
+ S2_CHECK(BN_exp(bn, bn, power, ctx));
451
+ S2_CHECK(BN_mul(bn, bn, bn_.get(), ctx));
452
+ BN_CTX_free(ctx);
453
+ BN_free(power);
454
+ bn_exp10 = bn_exp_;
455
+ }
456
+ // Now convert "bn" to a decimal string.
457
+ char* all_digits = BN_bn2dec(bn);
458
+ S2_DCHECK(all_digits != nullptr);
459
+ BN_free(bn);
460
+ // Check whether we have too many digits and round if necessary.
461
+ int num_digits = strlen(all_digits);
462
+ if (num_digits <= max_digits) {
463
+ *digits = all_digits;
464
+ } else {
465
+ digits->assign(all_digits, max_digits);
466
+ // Standard "printf" formatting rounds ties to an even number. This means
467
+ // that we round up (away from zero) if highest discarded digit is '5' or
468
+ // more, unless all other discarded digits are zero in which case we round
469
+ // up only if the lowest kept digit is odd.
470
+ if (all_digits[max_digits] >= '5' &&
471
+ ((all_digits[max_digits-1] & 1) == 1 ||
472
+ strpbrk(all_digits + max_digits + 1, "123456789") != nullptr)) {
473
+ // This can increase the number of digits by 1, but in that case at
474
+ // least one trailing zero will be stripped off below.
475
+ IncrementDecimalDigits(digits);
476
+ }
477
+ // Adjust the base-10 exponent to reflect the digits we have removed.
478
+ bn_exp10 += num_digits - max_digits;
479
+ }
480
+ OPENSSL_free(all_digits);
481
+
482
+ // Now strip any trailing zeros.
483
+ S2_DCHECK_NE((*digits)[0], '0');
484
+ string::iterator pos = digits->end();
485
+ while (pos[-1] == '0') --pos;
486
+ if (pos < digits->end()) {
487
+ bn_exp10 += digits->end() - pos;
488
+ digits->erase(pos, digits->end());
489
+ }
490
+ S2_DCHECK_LE(digits->size(), max_digits);
491
+
492
+ // Finally, we adjust the base-10 exponent so that the mantissa is a
493
+ // fraction in the range [0.1, 1) rather than an integer.
494
+ return bn_exp10 + digits->size();
495
+ }
496
+
497
+ string ExactFloat::ToUniqueString() const {
498
+ char prec_buf[20];
499
+ sprintf(prec_buf, "<%d>", prec());
500
+ return ToString() + prec_buf;
501
+ }
502
+
503
+ ExactFloat& ExactFloat::operator=(const ExactFloat& b) {
504
+ if (this != &b) {
505
+ sign_ = b.sign_;
506
+ bn_exp_ = b.bn_exp_;
507
+ BN_copy(bn_.get(), b.bn_.get());
508
+ }
509
+ return *this;
510
+ }
511
+
512
+ ExactFloat ExactFloat::operator-() const {
513
+ return CopyWithSign(-sign_);
514
+ }
515
+
516
+ ExactFloat operator+(const ExactFloat& a, const ExactFloat& b) {
517
+ return ExactFloat::SignedSum(a.sign_, &a, b.sign_, &b);
518
+ }
519
+
520
+ ExactFloat operator-(const ExactFloat& a, const ExactFloat& b) {
521
+ return ExactFloat::SignedSum(a.sign_, &a, -b.sign_, &b);
522
+ }
523
+
524
+ ExactFloat ExactFloat::SignedSum(int a_sign, const ExactFloat* a,
525
+ int b_sign, const ExactFloat* b) {
526
+ if (!a->is_normal() || !b->is_normal()) {
527
+ // Handle zero, infinity, and NaN according to IEEE 754-2008.
528
+ if (a->is_nan()) return *a;
529
+ if (b->is_nan()) return *b;
530
+ if (a->is_inf()) {
531
+ // Adding two infinities with opposite sign yields NaN.
532
+ if (b->is_inf() && a_sign != b_sign) return NaN();
533
+ return Infinity(a_sign);
534
+ }
535
+ if (b->is_inf()) return Infinity(b_sign);
536
+ if (a->is_zero()) {
537
+ if (!b->is_zero()) return b->CopyWithSign(b_sign);
538
+ // Adding two zeros with the same sign preserves the sign.
539
+ if (a_sign == b_sign) return SignedZero(a_sign);
540
+ // Adding two zeros of opposite sign produces +0.
541
+ return SignedZero(+1);
542
+ }
543
+ S2_DCHECK(b->is_zero());
544
+ return a->CopyWithSign(a_sign);
545
+ }
546
+ // Swap the numbers if necessary so that "a" has the larger bn_exp_.
547
+ if (a->bn_exp_ < b->bn_exp_) {
548
+ using std::swap;
549
+ swap(a_sign, b_sign);
550
+ swap(a, b);
551
+ }
552
+ // Shift "a" if necessary so that both values have the same bn_exp_.
553
+ ExactFloat r;
554
+ if (a->bn_exp_ > b->bn_exp_) {
555
+ S2_CHECK(BN_lshift(r.bn_.get(), a->bn_.get(), a->bn_exp_ - b->bn_exp_));
556
+ a = &r; // The only field of "a" used below is bn_.
557
+ }
558
+ r.bn_exp_ = b->bn_exp_;
559
+ if (a_sign == b_sign) {
560
+ S2_CHECK(BN_add(r.bn_.get(), a->bn_.get(), b->bn_.get()));
561
+ r.sign_ = a_sign;
562
+ } else {
563
+ // Note that the BIGNUM documentation is out of date -- all methods now
564
+ // allow the result to be the same as any input argument, so it is okay if
565
+ // (a == &r) due to the shift above.
566
+ S2_CHECK(BN_sub(r.bn_.get(), a->bn_.get(), b->bn_.get()));
567
+ if (BN_is_zero(r.bn_.get())) {
568
+ r.sign_ = +1;
569
+ } else if (BN_is_negative(r.bn_.get())) {
570
+ // The magnitude of "b" was larger.
571
+ r.sign_ = b_sign;
572
+ BN_set_negative(r.bn_.get(), false);
573
+ } else {
574
+ // They were equal, or the magnitude of "a" was larger.
575
+ r.sign_ = a_sign;
576
+ }
577
+ }
578
+ r.Canonicalize();
579
+ return r;
580
+ }
581
+
582
+ void ExactFloat::Canonicalize() {
583
+ if (!is_normal()) return;
584
+
585
+ // Underflow/overflow occurs if exp() is not in [kMinExp, kMaxExp].
586
+ // We also convert a zero mantissa to signed zero.
587
+ int my_exp = exp();
588
+ if (my_exp < kMinExp || BN_is_zero(bn_.get())) {
589
+ set_zero(sign_);
590
+ } else if (my_exp > kMaxExp) {
591
+ set_inf(sign_);
592
+ } else if (!BN_is_odd(bn_.get())) {
593
+ // Remove any low-order zero bits from the mantissa.
594
+ S2_DCHECK(!BN_is_zero(bn_.get()));
595
+ int shift = BN_ext_count_low_zero_bits(bn_.get());
596
+ if (shift > 0) {
597
+ S2_CHECK(BN_rshift(bn_.get(), bn_.get(), shift));
598
+ bn_exp_ += shift;
599
+ }
600
+ }
601
+ // If the mantissa has too many bits, we replace it by NaN to indicate
602
+ // that an inexact calculation has occurred.
603
+ if (prec() > kMaxPrec) {
604
+ set_nan();
605
+ }
606
+ }
607
+
608
+ ExactFloat operator*(const ExactFloat& a, const ExactFloat& b) {
609
+ int result_sign = a.sign_ * b.sign_;
610
+ if (!a.is_normal() || !b.is_normal()) {
611
+ // Handle zero, infinity, and NaN according to IEEE 754-2008.
612
+ if (a.is_nan()) return a;
613
+ if (b.is_nan()) return b;
614
+ if (a.is_inf()) {
615
+ // Infinity times zero yields NaN.
616
+ if (b.is_zero()) return ExactFloat::NaN();
617
+ return ExactFloat::Infinity(result_sign);
618
+ }
619
+ if (b.is_inf()) {
620
+ if (a.is_zero()) return ExactFloat::NaN();
621
+ return ExactFloat::Infinity(result_sign);
622
+ }
623
+ S2_DCHECK(a.is_zero() || b.is_zero());
624
+ return ExactFloat::SignedZero(result_sign);
625
+ }
626
+ ExactFloat r;
627
+ r.sign_ = result_sign;
628
+ r.bn_exp_ = a.bn_exp_ + b.bn_exp_;
629
+ BN_CTX* ctx = BN_CTX_new();
630
+ S2_CHECK(BN_mul(r.bn_.get(), a.bn_.get(), b.bn_.get(), ctx));
631
+ BN_CTX_free(ctx);
632
+ r.Canonicalize();
633
+ return r;
634
+ }
635
+
636
+ bool operator==(const ExactFloat& a, const ExactFloat& b) {
637
+ // NaN is not equal to anything, not even itself.
638
+ if (a.is_nan() || b.is_nan()) return false;
639
+
640
+ // Since Canonicalize() strips low-order zero bits, all other cases
641
+ // (including non-normal values) require bn_exp_ to be equal.
642
+ if (a.bn_exp_ != b.bn_exp_) return false;
643
+
644
+ // Positive and negative zero are equal.
645
+ if (a.is_zero() && b.is_zero()) return true;
646
+
647
+ // Otherwise, the signs and mantissas must match. Note that non-normal
648
+ // values such as infinity have a mantissa of zero.
649
+ return a.sign_ == b.sign_ && BN_ucmp(a.bn_.get(), b.bn_.get()) == 0;
650
+ }
651
+
652
+ int ExactFloat::ScaleAndCompare(const ExactFloat& b) const {
653
+ S2_DCHECK(is_normal() && b.is_normal() && bn_exp_ >= b.bn_exp_);
654
+ ExactFloat tmp = *this;
655
+ S2_CHECK(BN_lshift(tmp.bn_.get(), tmp.bn_.get(), bn_exp_ - b.bn_exp_));
656
+ return BN_ucmp(tmp.bn_.get(), b.bn_.get());
657
+ }
658
+
659
+ bool ExactFloat::UnsignedLess(const ExactFloat& b) const {
660
+ // Handle the zero/infinity cases (NaN has already been done).
661
+ if (is_inf() || b.is_zero()) return false;
662
+ if (is_zero() || b.is_inf()) return true;
663
+ // If the high-order bit positions differ, we are done.
664
+ int cmp = exp() - b.exp();
665
+ if (cmp != 0) return cmp < 0;
666
+ // Otherwise shift one of the two values so that they both have the same
667
+ // bn_exp_ and then compare the mantissas.
668
+ return (bn_exp_ >= b.bn_exp_ ?
669
+ ScaleAndCompare(b) < 0 : b.ScaleAndCompare(*this) > 0);
670
+ }
671
+
672
+ bool operator<(const ExactFloat& a, const ExactFloat& b) {
673
+ // NaN is unordered compared to everything, including itself.
674
+ if (a.is_nan() || b.is_nan()) return false;
675
+ // Positive and negative zero are equal.
676
+ if (a.is_zero() && b.is_zero()) return false;
677
+ // Otherwise, anything negative is less than anything positive.
678
+ if (a.sign_ != b.sign_) return a.sign_ < b.sign_;
679
+ // Now we just compare absolute values.
680
+ return (a.sign_ > 0) ? a.UnsignedLess(b) : b.UnsignedLess(a);
681
+ }
682
+
683
+ ExactFloat fabs(const ExactFloat& a) {
684
+ return abs(a);
685
+ }
686
+
687
+ ExactFloat abs(const ExactFloat& a) {
688
+ return a.CopyWithSign(+1);
689
+ }
690
+
691
+ ExactFloat fmax(const ExactFloat& a, const ExactFloat& b) {
692
+ // If one argument is NaN, return the other argument.
693
+ if (a.is_nan()) return b;
694
+ if (b.is_nan()) return a;
695
+ // Not required by IEEE 754, but we prefer +0 over -0.
696
+ if (a.sign_ != b.sign_) {
697
+ return (a.sign_ < b.sign_) ? b : a;
698
+ }
699
+ return (a < b) ? b : a;
700
+ }
701
+
702
+ ExactFloat fmin(const ExactFloat& a, const ExactFloat& b) {
703
+ // If one argument is NaN, return the other argument.
704
+ if (a.is_nan()) return b;
705
+ if (b.is_nan()) return a;
706
+ // Not required by IEEE 754, but we prefer -0 over +0.
707
+ if (a.sign_ != b.sign_) {
708
+ return (a.sign_ < b.sign_) ? a : b;
709
+ }
710
+ return (a < b) ? a : b;
711
+ }
712
+
713
+ ExactFloat fdim(const ExactFloat& a, const ExactFloat& b) {
714
+ // This formulation has the correct behavior for NaNs.
715
+ return (a <= b) ? 0 : (a - b);
716
+ }
717
+
718
+ ExactFloat ceil(const ExactFloat& a) {
719
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTowardPositive);
720
+ }
721
+
722
+ ExactFloat floor(const ExactFloat& a) {
723
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTowardNegative);
724
+ }
725
+
726
+ ExactFloat trunc(const ExactFloat& a) {
727
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTowardZero);
728
+ }
729
+
730
+ ExactFloat round(const ExactFloat& a) {
731
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTiesAwayFromZero);
732
+ }
733
+
734
+ ExactFloat rint(const ExactFloat& a) {
735
+ return a.RoundToPowerOf2(0, ExactFloat::kRoundTiesToEven);
736
+ }
737
+
738
+ template <class T>
739
+ T ExactFloat::ToInteger(RoundingMode mode) const {
740
+ using std::numeric_limits;
741
+ static_assert(sizeof(T) <= sizeof(uint64), "max 64 bits supported");
742
+ static_assert(numeric_limits<T>::is_signed, "only signed types supported");
743
+ const int64 kMinValue = numeric_limits<T>::min();
744
+ const int64 kMaxValue = numeric_limits<T>::max();
745
+
746
+ ExactFloat r = RoundToPowerOf2(0, mode);
747
+ if (r.is_nan()) return kMaxValue;
748
+ if (r.is_zero()) return 0;
749
+ if (!r.is_inf()) {
750
+ // If the unsigned value has more than 63 bits it is always clamped.
751
+ if (r.exp() < 64) {
752
+ int64 value = BN_ext_get_uint64(r.bn_.get()) << r.bn_exp_;
753
+ if (r.sign_ < 0) value = -value;
754
+ return max(kMinValue, min(kMaxValue, value));
755
+ }
756
+ }
757
+ return (r.sign_ < 0) ? kMinValue : kMaxValue;
758
+ }
759
+
760
+ long lrint(const ExactFloat& a) {
761
+ return a.ToInteger<long>(ExactFloat::kRoundTiesToEven);
762
+ }
763
+
764
+ long long llrint(const ExactFloat& a) {
765
+ return a.ToInteger<long long>(ExactFloat::kRoundTiesToEven);
766
+ }
767
+
768
+ long lround(const ExactFloat& a) {
769
+ return a.ToInteger<long>(ExactFloat::kRoundTiesAwayFromZero);
770
+ }
771
+
772
+ long long llround(const ExactFloat& a) {
773
+ return a.ToInteger<long long>(ExactFloat::kRoundTiesAwayFromZero);
774
+ }
775
+
776
+ ExactFloat copysign(const ExactFloat& a, const ExactFloat& b) {
777
+ return a.CopyWithSign(b.sign_);
778
+ }
779
+
780
+ ExactFloat frexp(const ExactFloat& a, int* exp) {
781
+ if (!a.is_normal()) {
782
+ // If a == 0, exp should be zero. If a.is_inf() or a.is_nan(), exp is not
783
+ // defined but the glibc implementation returns zero.
784
+ *exp = 0;
785
+ return a;
786
+ }
787
+ *exp = a.exp();
788
+ return ldexp(a, -a.exp());
789
+ }
790
+
791
+ ExactFloat ldexp(const ExactFloat& a, int exp) {
792
+ if (!a.is_normal()) return a;
793
+
794
+ // To prevent integer overflow, we first clamp "exp" so that
795
+ // (kMinExp - 1) <= (a_exp + exp) <= (kMaxExp + 1).
796
+ int a_exp = a.exp();
797
+ exp = min(ExactFloat::kMaxExp + 1 - a_exp,
798
+ max(ExactFloat::kMinExp - 1 + a_exp, exp));
799
+
800
+ // Now modify the exponent and check for overflow/underflow.
801
+ ExactFloat r = a;
802
+ r.bn_exp_ += exp;
803
+ r.Canonicalize();
804
+ return r;
805
+ }
806
+
807
+ ExactFloat scalbln(const ExactFloat& a, long exp) {
808
+ // Clamp the exponent to the range of "int" in order to avoid truncation.
809
+ exp = max(static_cast<long>(INT_MIN), min(static_cast<long>(INT_MAX), exp));
810
+ return ldexp(a, exp);
811
+ }
812
+
813
+ int ilogb(const ExactFloat& a) {
814
+ if (a.is_zero()) return FP_ILOGB0;
815
+ if (a.is_inf()) return INT_MAX;
816
+ if (a.is_nan()) return FP_ILOGBNAN;
817
+ // a.exp() assumes the significand is in the range [0.5, 1).
818
+ return a.exp() - 1;
819
+ }
820
+
821
+ ExactFloat logb(const ExactFloat& a) {
822
+ if (a.is_zero()) return ExactFloat::Infinity(-1);
823
+ if (a.is_inf()) return ExactFloat::Infinity(+1); // Even if a < 0.
824
+ if (a.is_nan()) return a;
825
+ // exp() assumes the significand is in the range [0.5,1).
826
+ return ExactFloat(a.exp() - 1);
827
+ }
828
+
829
+ ExactFloat ExactFloat::Unimplemented() {
830
+ S2_LOG(FATAL) << "Unimplemented ExactFloat method called";
831
+ return NaN();
832
+ }