test_core_math.odin 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304
  1. // Tests "math.odin" in "core:math".
  2. // Must be run with `-collection:tests=` flag, e.g.
  3. // ./odin run tests/core/math/test_core_math.odin -collection:tests=./tests
  4. package test_core_math
  5. import "core:fmt"
  6. import "core:math"
  7. import "core:testing"
  8. import tc "tests:common"
  9. main :: proc() {
  10. t := testing.T{}
  11. test_classify_f16(&t)
  12. test_classify_f32(&t)
  13. test_classify_f64(&t)
  14. test_trunc_f16(&t)
  15. test_trunc_f32(&t)
  16. test_trunc_f64(&t)
  17. test_round_f16(&t)
  18. test_round_f32(&t)
  19. test_round_f64(&t)
  20. test_nan(&t)
  21. test_acos(&t)
  22. test_acosh(&t)
  23. test_asin(&t)
  24. test_asinh(&t)
  25. test_atan(&t)
  26. test_atanh(&t)
  27. test_atan2(&t)
  28. test_cos(&t)
  29. test_cosh(&t)
  30. test_sin(&t)
  31. test_sinh(&t)
  32. test_sqrt(&t)
  33. test_tan(&t)
  34. test_tanh(&t)
  35. test_large_cos(&t)
  36. test_large_sin(&t)
  37. test_large_tan(&t)
  38. tc.report(&t)
  39. }
  40. @test
  41. test_classify_f16 :: proc(t: ^testing.T) {
  42. r: math.Float_Class
  43. Datum :: struct {
  44. i: int,
  45. v: f16,
  46. e: math.Float_Class,
  47. }
  48. @static data := []Datum{
  49. { 0, 1.2, .Normal },
  50. { 1, 0h0001, .Subnormal },
  51. { 2, 0.0, .Zero },
  52. { 3, -0.0, .Neg_Zero },
  53. { 4, math.SNAN_F16, .NaN },
  54. { 5, math.QNAN_F16, .NaN },
  55. { 6, math.INF_F16, .Inf },
  56. { 7, math.NEG_INF_F16, .Neg_Inf },
  57. }
  58. for d, i in data {
  59. assert(i == d.i)
  60. r = math.classify_f16(d.v)
  61. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e))
  62. }
  63. /* Check all subnormals (exponent 0, 10-bit significand non-zero) */
  64. for i in u16(1)..<0x400 {
  65. v := transmute(f16)i
  66. r = math.classify_f16(v)
  67. e :: math.Float_Class.Subnormal
  68. tc.expect(t, r == e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, v, r, e))
  69. }
  70. }
  71. @test
  72. test_classify_f32 :: proc(t: ^testing.T) {
  73. r: math.Float_Class
  74. Datum :: struct {
  75. i: int,
  76. v: f32,
  77. e: math.Float_Class,
  78. }
  79. @static data := []Datum{
  80. { 0, 1.2, .Normal },
  81. { 1, 0h0000_0001, .Subnormal },
  82. { 2, 0.0, .Zero },
  83. { 3, -0.0, .Neg_Zero },
  84. { 4, math.SNAN_F32, .NaN },
  85. { 5, math.QNAN_F32, .NaN },
  86. { 6, math.INF_F32, .Inf },
  87. { 7, math.NEG_INF_F32, .Neg_Inf },
  88. }
  89. for d, i in data {
  90. assert(i == d.i)
  91. r = math.classify_f32(d.v)
  92. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e))
  93. }
  94. }
  95. @test
  96. test_classify_f64 :: proc(t: ^testing.T) {
  97. r: math.Float_Class
  98. Datum :: struct {
  99. i: int,
  100. v: f64,
  101. e: math.Float_Class,
  102. }
  103. @static data := []Datum{
  104. { 0, 1.2, .Normal },
  105. { 1, 0h0000_0000_0000_0001, .Subnormal },
  106. { 2, 0.0, .Zero },
  107. { 3, -0.0, .Neg_Zero },
  108. { 4, math.SNAN_F64, .NaN },
  109. { 5, math.QNAN_F64, .NaN },
  110. { 6, math.INF_F64, .Inf },
  111. { 7, math.NEG_INF_F64, .Neg_Inf },
  112. }
  113. for d, i in data {
  114. assert(i == d.i)
  115. r = math.classify_f64(d.v)
  116. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e))
  117. }
  118. }
  119. @test
  120. test_trunc_f16 :: proc(t: ^testing.T) {
  121. r, v: f16
  122. Datum :: struct {
  123. i: int,
  124. v: f16,
  125. e: f16,
  126. }
  127. @static data := []Datum{
  128. { 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken
  129. { 1, -10.5, -10 },
  130. { 2, math.F16_MAX, math.F16_MAX },
  131. { 3, -math.F16_MAX, -math.F16_MAX },
  132. { 4, math.F16_MIN, 0.0 },
  133. { 5, -math.F16_MIN, -0.0 },
  134. { 6, 0.0, 0.0 },
  135. { 7, -0.0, -0.0 },
  136. { 8, 1, 1 },
  137. { 9, -1, -1 },
  138. { 10, math.INF_F16, math.INF_F16 },
  139. { 11, math.NEG_INF_F16, math.NEG_INF_F16 },
  140. /* From https://en.wikipedia.org/wiki/Half-precision_floating-point_format */
  141. { 12, 0h3C01, 1 }, // 0x1.004p+0 (smallest > 1)
  142. { 13, -0h3C01, -1 },
  143. { 14, 0h3BFF, 0.0 }, // 0x1.ffcp-1 (largest < 1)
  144. { 15, -0h3BFF, -0.0 },
  145. { 16, 0h0001, 0.0 }, // 0x0.004p-14 (smallest subnormal)
  146. { 17, -0h0001, -0.0 },
  147. { 18, 0h03FF, 0.0 }, // 0x0.ffcp-14 (largest subnormal)
  148. { 19, -0h03FF, -0.0 },
  149. { 20, 0hC809, -8 }, // -0x1.024p+3
  150. { 21, 0h4458, 4 }, // 0x1.16p+2
  151. }
  152. for d, i in data {
  153. assert(i == d.i)
  154. r = math.trunc_f16(d.v)
  155. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
  156. }
  157. v = math.SNAN_F16
  158. r = math.trunc_f16(v)
  159. tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  160. v = math.QNAN_F16
  161. r = math.trunc_f16(v)
  162. tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  163. }
  164. @test
  165. test_trunc_f32 :: proc(t: ^testing.T) {
  166. r, v: f32
  167. Datum :: struct {
  168. i: int,
  169. v: f32,
  170. e: f32,
  171. }
  172. @static data := []Datum{
  173. { 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken
  174. { 1, -10.5, -10 },
  175. { 2, math.F32_MAX, math.F32_MAX },
  176. { 3, -math.F32_MAX, -math.F32_MAX },
  177. { 4, math.F32_MIN, 0.0 },
  178. { 5, -math.F32_MIN, -0.0 },
  179. { 6, 0.0, 0.0 },
  180. { 7, -0.0, -0.0 },
  181. { 8, 1, 1 },
  182. { 9, -1, -1 },
  183. { 10, math.INF_F32, math.INF_F32 },
  184. { 11, math.NEG_INF_F32, math.NEG_INF_F32 },
  185. /* From https://en.wikipedia.org/wiki/Single-precision_floating-point_format */
  186. { 12, 0h3F80_0001, 1 }, // 0x1.000002p+0 (smallest > 1)
  187. { 13, -0h3F80_0001, -1 },
  188. { 14, 0h3F7F_FFFF, 0.0 }, // 0x1.fffffep-1 (largest < 1)
  189. { 15, -0h3F7F_FFFF, -0.0 },
  190. { 16, 0h0000_0001, 0.0 }, // 0x0.000002p-126 (smallest subnormal)
  191. { 17, -0h0000_0001, -0.0 },
  192. { 18, 0h007F_FFFF, 0.0 }, // 0x0.fffffep-126 (largest subnormal)
  193. { 19, -0h007F_FFFF, -0.0 },
  194. /* From libc-test src/math/sanity/truncf.h */
  195. { 20, 0hC101_11D0, -8 }, // -0x1.0223ap+3
  196. { 21, 0h408B_0C34, 4 }, // 0x1.161868p+2
  197. { 22, 0hC106_1A5A, -8 }, // -0x1.0c34b4p+3
  198. { 23, 0hC0D1_0378, -6 }, // -0x1.a206fp+2
  199. { 24, 0h4114_45DE, 9 }, // 0x1.288bbcp+3
  200. { 25, 0h3F29_77E8, 0.0 }, // 0x1.52efdp-1
  201. { 26, 0hBED0_2E64, -0.0 }, // -0x1.a05cc8p-2
  202. { 27, 0h3F0F_CF7D, 0.0 }, // 0x1.1f9efap-1
  203. { 28, 0h3F46_2ED8, 0.0 }, // 0x1.8c5dbp-1
  204. { 29, 0hBF2D_C375, -0.0 }, // -0x1.5b86eap-1
  205. }
  206. for d, i in data {
  207. assert(i == d.i)
  208. r = math.trunc_f32(d.v)
  209. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
  210. }
  211. v = math.SNAN_F32
  212. r = math.trunc_f32(v)
  213. tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  214. v = math.QNAN_F32
  215. r = math.trunc_f32(v)
  216. tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  217. }
  218. @test
  219. test_trunc_f64 :: proc(t: ^testing.T) {
  220. r, v: f64
  221. Datum :: struct {
  222. i: int,
  223. v: f64,
  224. e: f64,
  225. }
  226. data := []Datum{
  227. { 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken
  228. { 1, -10.5, -10 },
  229. { 2, math.F64_MAX, math.F64_MAX },
  230. { 3, -math.F64_MAX, -math.F64_MAX },
  231. { 4, math.F64_MIN, 0.0 },
  232. { 5, -math.F64_MIN, -0.0 },
  233. { 6, 0.0, 0.0 },
  234. { 7, -0.0, -0.0 },
  235. { 8, 1, 1 },
  236. { 9, -1, -1 },
  237. { 10, math.INF_F64, math.INF_F64 },
  238. { 11, math.NEG_INF_F64, math.NEG_INF_F64 },
  239. /* From https://en.wikipedia.org/wiki/Double-precision_floating-point_format */
  240. { 12, 0h3FF0_0000_0000_0001, 1 }, // 0x1.0000000000001p+0 (smallest > 1)
  241. { 13, -0h3FF0_0000_0000_0001, -1 },
  242. { 14, 0h3FEF_FFFF_FFFF_FFFF, 0.0 }, // 0x1.fffffffffffffp-1 (largest < 1)
  243. { 15, -0h3FEF_FFFF_FFFF_FFFF, -0.0 },
  244. { 16, 0h0000_0000_0000_0001, 0.0 }, // 0x0.0000000000001p-1022 (smallest subnormal)
  245. { 17, -0h0000_0000_0000_0001, -0.0 },
  246. { 18, 0h000F_FFFF_FFFF_FFFF, 0.0 }, // 0x0.fffffffffffffp-1022 (largest subnormal)
  247. { 19, -0h000F_FFFF_FFFF_FFFF, -0.0 },
  248. /* From libc-test src/math/sanity/trunc.h */
  249. { 20, 0hC020_2239_F3C6_A8F1, -8 }, // -0x1.02239f3c6a8f1p+3
  250. { 21, 0h4011_6186_8E18_BC67, 4 }, // 0x1.161868e18bc67p+2
  251. { 22, 0hC020_C34B_3E01_E6E7, -8 }, // -0x1.0c34b3e01e6e7p+3
  252. { 23, 0hC01A_206F_0A19_DCC4, -6 }, // -0x1.a206f0a19dcc4p+2
  253. { 24, 0h4022_88BB_B0D6_A1E6, 9 }, // 0x1.288bbb0d6a1e6p+3
  254. { 25, 0h3FE5_2EFD_0CD8_0497, 0.0 }, // 0x1.52efd0cd80497p-1
  255. { 26, 0hBFDA_05CC_7544_81D1, -0.0 }, // -0x1.a05cc754481d1p-2
  256. { 27, 0h3FE1_F9EF_9347_45CB, 0.0 }, // 0x1.1f9ef934745cbp-1
  257. { 28, 0h3FE8_C5DB_097F_7442, 0.0 }, // 0x1.8c5db097f7442p-1
  258. { 29, 0hBFE5_B86E_A811_8A0E, -0.0 }, // -0x1.5b86ea8118a0ep-1
  259. }
  260. for d, i in data {
  261. assert(i == d.i)
  262. r = math.trunc_f64(d.v)
  263. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
  264. }
  265. v = math.SNAN_F64
  266. r = math.trunc_f64(v)
  267. tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  268. v = math.QNAN_F64
  269. r = math.trunc_f64(v)
  270. tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  271. }
  272. @test
  273. test_round_f16 :: proc(t: ^testing.T) {
  274. r, v: f16
  275. Datum :: struct {
  276. i: int,
  277. v: f16,
  278. e: f16,
  279. }
  280. @static data := []Datum{
  281. { 0, 10.5, 11 },
  282. { 1, -10.5, -11 },
  283. { 2, math.F16_MAX, math.F16_MAX },
  284. { 3, -math.F16_MAX, -math.F16_MAX },
  285. { 4, math.F16_MIN, 0.0 },
  286. { 5, -math.F16_MIN, -0.0 },
  287. { 6, 0.0, 0.0 },
  288. { 7, -0.0, -0.0 },
  289. { 8, 1, 1 },
  290. { 9, -1, -1 },
  291. { 10, math.INF_F16, math.INF_F16 },
  292. { 11, math.NEG_INF_F16, math.NEG_INF_F16 },
  293. /* From https://en.wikipedia.org/wiki/Half-precision_floating-point_format */
  294. { 12, 0h3C01, 1 }, // 0x1.004p+0 (smallest > 1)
  295. { 13, -0h3C01, -1 },
  296. { 14, 0h3BFF, 1 }, // 0x1.ffcp-1 (largest < 1)
  297. { 15, -0h3BFF, -1 },
  298. { 16, 0h0001, 0.0 }, // 0x0.004p-14 (smallest subnormal)
  299. { 17, -0h0001, -0.0 },
  300. { 18, 0h03FF, 0.0 }, // 0x0.ffcp-14 (largest subnormal)
  301. { 19, -0h03FF, -0.0 },
  302. { 20, 0hC809, -8 }, // -0x1.024p+3
  303. { 21, 0h4458, 4 }, // 0x1.16p+2
  304. }
  305. for d, i in data {
  306. assert(i == d.i)
  307. r = math.round_f16(d.v)
  308. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
  309. }
  310. v = math.SNAN_F16
  311. r = math.round_f16(v)
  312. tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  313. v = math.QNAN_F16
  314. r = math.round_f16(v)
  315. tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  316. }
  317. @test
  318. test_round_f32 :: proc(t: ^testing.T) {
  319. r, v: f32
  320. Datum :: struct {
  321. i: int,
  322. v: f32,
  323. e: f32,
  324. }
  325. @static data := []Datum{
  326. { 0, 10.5, 11 },
  327. { 1, -10.5, -11 },
  328. { 2, math.F32_MAX, math.F32_MAX },
  329. { 3, -math.F32_MAX, -math.F32_MAX },
  330. { 4, math.F32_MIN, 0.0 },
  331. { 5, -math.F32_MIN, -0.0 },
  332. { 6, 0.0, 0.0 },
  333. { 7, -0.0, -0.0 },
  334. { 8, 1, 1 },
  335. { 9, -1, -1 },
  336. { 10, math.INF_F32, math.INF_F32 },
  337. { 11, math.NEG_INF_F32, math.NEG_INF_F32 },
  338. /* From https://en.wikipedia.org/wiki/Single-precision_floating-point_format */
  339. { 12, 0h3F80_0001, 1 }, // 0x1.000002p+0 (smallest > 1)
  340. { 13, -0h3F80_0001, -1 },
  341. { 14, 0h3F7F_FFFF, 1 }, // 0x1.fffffep-1 (largest < 1)
  342. { 15, -0h3F7F_FFFF, -1 },
  343. { 16, 0h0000_0001, 0.0 }, // 0x0.000002p-126 (smallest subnormal)
  344. { 17, -0h0000_0001, -0.0 },
  345. { 18, 0h007F_FFFF, 0.0 }, // 0x0.fffffep-126 (largest subnormal)
  346. { 19, -0h007F_FFFF, -0.0 },
  347. /* From libc-test src/math/sanity/roundf.h */
  348. { 20, 0hC101_11D0, -8 }, // -0x1.0223ap+3
  349. { 21, 0h408B_0C34, 4 }, // 0x1.161868p+2
  350. { 22, 0hC106_1A5A, -8 }, // -0x1.0c34b4p+3
  351. { 23, 0hC0D1_0378, -7 }, // -0x1.a206fp+2
  352. { 24, 0h4114_45DE, 9 }, // 0x1.288bbcp+3
  353. { 25, 0h3F29_77E8, 1.0 }, // 0x1.52efdp-1
  354. { 26, 0hBED0_2E64, -0.0 }, // -0x1.a05cc8p-2
  355. { 27, 0h3F0F_CF7D, 1.0 }, // 0x1.1f9efap-1
  356. { 28, 0h3F46_2ED8, 1.0 }, // 0x1.8c5dbp-1
  357. { 29, 0hBF2D_C375, -1.0 }, // -0x1.5b86eap-1
  358. }
  359. for d, i in data {
  360. assert(i == d.i)
  361. r = math.round_f32(d.v)
  362. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
  363. }
  364. v = math.SNAN_F32
  365. r = math.round_f32(v)
  366. tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  367. v = math.QNAN_F32
  368. r = math.round_f32(v)
  369. tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  370. }
  371. @test
  372. test_round_f64 :: proc(t: ^testing.T) {
  373. r, v: f64
  374. Datum :: struct {
  375. i: int,
  376. v: f64,
  377. e: f64,
  378. }
  379. data := []Datum{
  380. { 0, 10.5, 11 }, // Issue #1574 fract in linalg/glm is broken
  381. { 1, -10.5, -11 },
  382. { 2, math.F64_MAX, math.F64_MAX },
  383. { 3, -math.F64_MAX, -math.F64_MAX },
  384. { 4, math.F64_MIN, 0.0 },
  385. { 5, -math.F64_MIN, -0.0 },
  386. { 6, 0.0, 0.0 },
  387. { 7, -0.0, -0.0 },
  388. { 8, 1, 1 },
  389. { 9, -1, -1 },
  390. { 10, math.INF_F64, math.INF_F64 },
  391. { 11, math.NEG_INF_F64, math.NEG_INF_F64 },
  392. /* From https://en.wikipedia.org/wiki/Double-precision_floating-point_format */
  393. { 12, 0h3FF0_0000_0000_0001, 1 }, // 0x1.0000000000001p+0 (smallest > 1)
  394. { 13, -0h3FF0_0000_0000_0001, -1 },
  395. { 14, 0h3FEF_FFFF_FFFF_FFFF, 1 }, // 0x1.fffffffffffffp-1 (largest < 1)
  396. { 15, -0h3FEF_FFFF_FFFF_FFFF, -1 },
  397. { 16, 0h0000_0000_0000_0001, 0.0 }, // 0x0.0000000000001p-1022 (smallest subnormal)
  398. { 17, -0h0000_0000_0000_0001, -0.0 },
  399. { 18, 0h000F_FFFF_FFFF_FFFF, 0.0 }, // 0x0.fffffffffffffp-1022 (largest subnormal)
  400. { 19, -0h000F_FFFF_FFFF_FFFF, -0.0 },
  401. /* From libc-test src/math/sanity/round.h */
  402. { 20, 0hC020_2239_F3C6_A8F1, -8 }, // -0x1.02239f3c6a8f1p+3
  403. { 21, 0h4011_6186_8E18_BC67, 4 }, // 0x1.161868e18bc67p+2
  404. { 22, 0hC020_C34B_3E01_E6E7, -8 }, // -0x1.0c34b3e01e6e7p+3
  405. { 23, 0hC01A_206F_0A19_DCC4, -7 }, // -0x1.a206f0a19dcc4p+2
  406. { 24, 0h4022_88BB_B0D6_A1E6, 9 }, // 0x1.288bbb0d6a1e6p+3
  407. { 25, 0h3FE5_2EFD_0CD8_0497, 1.0 }, // 0x1.52efd0cd80497p-1
  408. { 26, 0hBFDA_05CC_7544_81D1, -0.0 }, // -0x1.a05cc754481d1p-2
  409. { 27, 0h3FE1_F9EF_9347_45CB, 1.0 }, // 0x1.1f9ef934745cbp-1
  410. { 28, 0h3FE8_C5DB_097F_7442, 1.0 }, // 0x1.8c5db097f7442p-1
  411. { 29, 0hBFE5_B86E_A811_8A0E, -1.0 }, // -0x1.5b86ea8118a0ep-1
  412. }
  413. for d, i in data {
  414. assert(i == d.i)
  415. r = math.round_f64(d.v)
  416. tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
  417. }
  418. v = math.SNAN_F64
  419. r = math.round_f64(v)
  420. tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  421. v = math.QNAN_F64
  422. r = math.round_f64(v)
  423. tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
  424. }
  425. vf := []f64{
  426. 4.9790119248836735e+00,
  427. 7.7388724745781045e+00,
  428. -2.7688005719200159e-01,
  429. -5.0106036182710749e+00,
  430. 9.6362937071984173e+00,
  431. 2.9263772392439646e+00,
  432. 5.2290834314593066e+00,
  433. 2.7279399104360102e+00,
  434. 1.8253080916808550e+00,
  435. -8.6859247685756013e+00,
  436. }
  437. // The expected results below were computed by the high precision calculators at https://keisan.casio.com/.
  438. acos := []f64{
  439. 1.0496193546107222142571536e+00,
  440. 6.8584012813664425171660692e-01,
  441. 1.5984878714577160325521819e+00,
  442. 2.0956199361475859327461799e+00,
  443. 2.7053008467824138592616927e-01,
  444. 1.2738121680361776018155625e+00,
  445. 1.0205369421140629186287407e+00,
  446. 1.2945003481781246062157835e+00,
  447. 1.3872364345374451433846657e+00,
  448. 2.6231510803970463967294145e+00,
  449. }
  450. acosh := []f64{
  451. 2.4743347004159012494457618e+00,
  452. 2.8576385344292769649802701e+00,
  453. 7.2796961502981066190593175e-01,
  454. 2.4796794418831451156471977e+00,
  455. 3.0552020742306061857212962e+00,
  456. 2.044238592688586588942468e+00,
  457. 2.5158701513104513595766636e+00,
  458. 1.99050839282411638174299e+00,
  459. 1.6988625798424034227205445e+00,
  460. 2.9611454842470387925531875e+00,
  461. }
  462. asin := []f64{
  463. 5.2117697218417440497416805e-01,
  464. 8.8495619865825236751471477e-01,
  465. -02.769154466281941332086016e-02,
  466. -5.2482360935268931351485822e-01,
  467. 1.3002662421166552333051524e+00,
  468. 2.9698415875871901741575922e-01,
  469. 5.5025938468083370060258102e-01,
  470. 2.7629597861677201301553823e-01,
  471. 1.83559892257451475846656e-01,
  472. -1.0523547536021497774980928e+00,
  473. }
  474. asinh := []f64{
  475. 2.3083139124923523427628243e+00,
  476. 2.743551594301593620039021e+00,
  477. -2.7345908534880091229413487e-01,
  478. -2.3145157644718338650499085e+00,
  479. 2.9613652154015058521951083e+00,
  480. 1.7949041616585821933067568e+00,
  481. 2.3564032905983506405561554e+00,
  482. 1.7287118790768438878045346e+00,
  483. 1.3626658083714826013073193e+00,
  484. -2.8581483626513914445234004e+00,
  485. }
  486. atan := []f64{
  487. 1.372590262129621651920085e+00,
  488. 1.442290609645298083020664e+00,
  489. -2.7011324359471758245192595e-01,
  490. -1.3738077684543379452781531e+00,
  491. 1.4673921193587666049154681e+00,
  492. 1.2415173565870168649117764e+00,
  493. 1.3818396865615168979966498e+00,
  494. 1.2194305844639670701091426e+00,
  495. 1.0696031952318783760193244e+00,
  496. -1.4561721938838084990898679e+00,
  497. }
  498. atanh := []f64{
  499. 5.4651163712251938116878204e-01,
  500. 1.0299474112843111224914709e+00,
  501. -2.7695084420740135145234906e-02,
  502. -5.5072096119207195480202529e-01,
  503. 1.9943940993171843235906642e+00,
  504. 3.01448604578089708203017e-01,
  505. 5.8033427206942188834370595e-01,
  506. 2.7987997499441511013958297e-01,
  507. 1.8459947964298794318714228e-01,
  508. -1.3273186910532645867272502e+00,
  509. }
  510. atan2 := []f64{
  511. 1.1088291730037004444527075e+00,
  512. 9.1218183188715804018797795e-01,
  513. 1.5984772603216203736068915e+00,
  514. 2.0352918654092086637227327e+00,
  515. 8.0391819139044720267356014e-01,
  516. 1.2861075249894661588866752e+00,
  517. 1.0889904479131695712182587e+00,
  518. 1.3044821793397925293797357e+00,
  519. 1.3902530903455392306872261e+00,
  520. 2.2859857424479142655411058e+00,
  521. }
  522. cos := []f64{
  523. 2.634752140995199110787593e-01,
  524. 1.148551260848219865642039e-01,
  525. 9.6191297325640768154550453e-01,
  526. 2.938141150061714816890637e-01,
  527. -9.777138189897924126294461e-01,
  528. -9.7693041344303219127199518e-01,
  529. 4.940088096948647263961162e-01,
  530. -9.1565869021018925545016502e-01,
  531. -2.517729313893103197176091e-01,
  532. -7.39241351595676573201918e-01,
  533. }
  534. // Results for 1e5 * Pi + vf[i]
  535. cosLarge := []f64{
  536. 2.634752141185559426744e-01,
  537. 1.14855126055543100712e-01,
  538. 9.61912973266488928113e-01,
  539. 2.9381411499556122552e-01,
  540. -9.777138189880161924641e-01,
  541. -9.76930413445147608049e-01,
  542. 4.940088097314976789841e-01,
  543. -9.15658690217517835002e-01,
  544. -2.51772931436786954751e-01,
  545. -7.3924135157173099849e-01,
  546. }
  547. cosh := []f64{
  548. 7.2668796942212842775517446e+01,
  549. 1.1479413465659254502011135e+03,
  550. 1.0385767908766418550935495e+00,
  551. 7.5000957789658051428857788e+01,
  552. 7.655246669605357888468613e+03,
  553. 9.3567491758321272072888257e+00,
  554. 9.331351599270605471131735e+01,
  555. 7.6833430994624643209296404e+00,
  556. 3.1829371625150718153881164e+00,
  557. 2.9595059261916188501640911e+03,
  558. }
  559. sin := []f64{
  560. -9.6466616586009283766724726e-01,
  561. 9.9338225271646545763467022e-01,
  562. -2.7335587039794393342449301e-01,
  563. 9.5586257685042792878173752e-01,
  564. -2.099421066779969164496634e-01,
  565. 2.135578780799860532750616e-01,
  566. -8.694568971167362743327708e-01,
  567. 4.019566681155577786649878e-01,
  568. 9.6778633541687993721617774e-01,
  569. -6.734405869050344734943028e-01,
  570. }
  571. // Results for 1e5 * Pi + vf[i]
  572. sinLarge := []f64{
  573. -9.646661658548936063912e-01,
  574. 9.933822527198506903752e-01,
  575. -2.7335587036246899796e-01,
  576. 9.55862576853689321268e-01,
  577. -2.099421066862688873691e-01,
  578. 2.13557878070308981163e-01,
  579. -8.694568970959221300497e-01,
  580. 4.01956668098863248917e-01,
  581. 9.67786335404528727927e-01,
  582. -6.7344058693131973066e-01,
  583. }
  584. sinh := []f64{
  585. 7.2661916084208532301448439e+01,
  586. 1.1479409110035194500526446e+03,
  587. -2.8043136512812518927312641e-01,
  588. -7.499429091181587232835164e+01,
  589. 7.6552466042906758523925934e+03,
  590. 9.3031583421672014313789064e+00,
  591. 9.330815755828109072810322e+01,
  592. 7.6179893137269146407361477e+00,
  593. 3.021769180549615819524392e+00,
  594. -2.95950575724449499189888e+03,
  595. }
  596. sqrt := []f64{
  597. 2.2313699659365484748756904e+00,
  598. 2.7818829009464263511285458e+00,
  599. 5.2619393496314796848143251e-01,
  600. 2.2384377628763938724244104e+00,
  601. 3.1042380236055381099288487e+00,
  602. 1.7106657298385224403917771e+00,
  603. 2.286718922705479046148059e+00,
  604. 1.6516476350711159636222979e+00,
  605. 1.3510396336454586262419247e+00,
  606. 2.9471892997524949215723329e+00,
  607. }
  608. tan := []f64{
  609. -3.661316565040227801781974e+00,
  610. 8.64900232648597589369854e+00,
  611. -2.8417941955033612725238097e-01,
  612. 3.253290185974728640827156e+00,
  613. 2.147275640380293804770778e-01,
  614. -2.18600910711067004921551e-01,
  615. -1.760002817872367935518928e+00,
  616. -4.389808914752818126249079e-01,
  617. -3.843885560201130679995041e+00,
  618. 9.10988793377685105753416e-01,
  619. }
  620. // Results for 1e5 * Pi + vf[i]
  621. tanLarge := []f64{
  622. -3.66131656475596512705e+00,
  623. 8.6490023287202547927e+00,
  624. -2.841794195104782406e-01,
  625. 3.2532901861033120983e+00,
  626. 2.14727564046880001365e-01,
  627. -2.18600910700688062874e-01,
  628. -1.760002817699722747043e+00,
  629. -4.38980891453536115952e-01,
  630. -3.84388555942723509071e+00,
  631. 9.1098879344275101051e-01,
  632. }
  633. tanh := []f64{
  634. 9.9990531206936338549262119e-01,
  635. 9.9999962057085294197613294e-01,
  636. -2.7001505097318677233756845e-01,
  637. -9.9991110943061718603541401e-01,
  638. 9.9999999146798465745022007e-01,
  639. 9.9427249436125236705001048e-01,
  640. 9.9994257600983138572705076e-01,
  641. 9.9149409509772875982054701e-01,
  642. 9.4936501296239685514466577e-01,
  643. -9.9999994291374030946055701e-01,
  644. }
  645. NaN :: 0h7fff_ffff_ffff_ffff
  646. Pi :: 0h4009_21fb_5444_2d18
  647. // arguments and expected results for special cases
  648. vfacos_sc := []f64{
  649. -Pi,
  650. 1,
  651. Pi,
  652. NaN,
  653. }
  654. acos_sc := []f64{
  655. NaN,
  656. 0,
  657. NaN,
  658. NaN,
  659. }
  660. vfacosh_sc := []f64{
  661. math.inf_f64(-1),
  662. 0.5,
  663. 1,
  664. math.inf_f64(1),
  665. NaN,
  666. }
  667. acosh_sc := []f64{
  668. NaN,
  669. NaN,
  670. 0,
  671. math.inf_f64(1),
  672. NaN,
  673. }
  674. vfasin_sc := []f64{
  675. -Pi,
  676. math.copy_sign_f64(0, -1),
  677. 0,
  678. Pi,
  679. NaN,
  680. }
  681. asin_sc := []f64{
  682. NaN,
  683. math.copy_sign_f64(0, -1),
  684. 0,
  685. NaN,
  686. NaN,
  687. }
  688. vfasinh_sc := []f64{
  689. math.inf_f64(-1),
  690. math.copy_sign_f64(0, -1),
  691. 0,
  692. math.inf_f64(1),
  693. NaN,
  694. }
  695. asinh_sc := []f64{
  696. math.inf_f64(-1),
  697. math.copy_sign_f64(0, -1),
  698. 0,
  699. math.inf_f64(1),
  700. NaN,
  701. }
  702. vfatan_sc := []f64{
  703. math.inf_f64(-1),
  704. math.copy_sign_f64(0, -1),
  705. 0,
  706. math.inf_f64(1),
  707. NaN,
  708. }
  709. atan_sc := []f64{
  710. -Pi / 2,
  711. math.copy_sign_f64(0, -1),
  712. 0,
  713. Pi / 2,
  714. NaN,
  715. }
  716. vfatanh_sc := []f64{
  717. math.inf_f64(-1),
  718. -Pi,
  719. -1,
  720. math.copy_sign_f64(0, -1),
  721. 0,
  722. 1,
  723. Pi,
  724. math.inf_f64(1),
  725. NaN,
  726. }
  727. atanh_sc := []f64{
  728. NaN,
  729. NaN,
  730. math.inf_f64(-1),
  731. math.copy_sign_f64(0, -1),
  732. 0,
  733. math.inf_f64(1),
  734. NaN,
  735. NaN,
  736. NaN,
  737. }
  738. vfatan2_sc := [][2]f64{
  739. {math.inf_f64(-1), math.inf_f64(-1)},
  740. {math.inf_f64(-1), -Pi},
  741. {math.inf_f64(-1), 0},
  742. {math.inf_f64(-1), +Pi},
  743. {math.inf_f64(-1), math.inf_f64(1)},
  744. {math.inf_f64(-1), NaN},
  745. {-Pi, math.inf_f64(-1)},
  746. {-Pi, 0},
  747. {-Pi, math.inf_f64(1)},
  748. {-Pi, NaN},
  749. {math.copy_sign_f64(0, -1), math.inf_f64(-1)},
  750. {math.copy_sign_f64(0, -1), -Pi},
  751. {math.copy_sign_f64(0, -1), math.copy_sign_f64(0, -1)},
  752. {math.copy_sign_f64(0, -1), 0},
  753. {math.copy_sign_f64(0, -1), +Pi},
  754. {math.copy_sign_f64(0, -1), math.inf_f64(1)},
  755. {math.copy_sign_f64(0, -1), NaN},
  756. {0, math.inf_f64(-1)},
  757. {0, -Pi},
  758. {0, math.copy_sign_f64(0, -1)},
  759. {0, 0},
  760. {0, +Pi},
  761. {0, math.inf_f64(1)},
  762. {0, NaN},
  763. {+Pi, math.inf_f64(-1)},
  764. {+Pi, 0},
  765. {+Pi, math.inf_f64(1)},
  766. {1.0, math.inf_f64(1)},
  767. {-1.0, math.inf_f64(1)},
  768. {+Pi, NaN},
  769. {math.inf_f64(1), math.inf_f64(-1)},
  770. {math.inf_f64(1), -Pi},
  771. {math.inf_f64(1), 0},
  772. {math.inf_f64(1), +Pi},
  773. {math.inf_f64(1), math.inf_f64(1)},
  774. {math.inf_f64(1), NaN},
  775. {NaN, NaN},
  776. }
  777. atan2_sc := []f64{
  778. -3 * Pi / 4, // atan2(-Inf, -Inf)
  779. -Pi / 2, // atan2(-Inf, -Pi)
  780. -Pi / 2, // atan2(-Inf, +0)
  781. -Pi / 2, // atan2(-Inf, +Pi)
  782. -Pi / 4, // atan2(-Inf, +Inf)
  783. NaN, // atan2(-Inf, NaN)
  784. -Pi, // atan2(-Pi, -Inf)
  785. -Pi / 2, // atan2(-Pi, +0)
  786. math.copy_sign_f64(0, -1), // atan2(-Pi, Inf)
  787. NaN, // atan2(-Pi, NaN)
  788. -Pi, // atan2(-0, -Inf)
  789. -Pi, // atan2(-0, -Pi)
  790. -Pi, // atan2(-0, -0)
  791. math.copy_sign_f64(0, -1), // atan2(-0, +0)
  792. math.copy_sign_f64(0, -1), // atan2(-0, +Pi)
  793. math.copy_sign_f64(0, -1), // atan2(-0, +Inf)
  794. NaN, // atan2(-0, NaN)
  795. Pi, // atan2(+0, -Inf)
  796. Pi, // atan2(+0, -Pi)
  797. Pi, // atan2(+0, -0)
  798. 0, // atan2(+0, +0)
  799. 0, // atan2(+0, +Pi)
  800. 0, // atan2(+0, +Inf)
  801. NaN, // atan2(+0, NaN)
  802. Pi, // atan2(+Pi, -Inf)
  803. Pi / 2, // atan2(+Pi, +0)
  804. 0, // atan2(+Pi, +Inf)
  805. 0, // atan2(+1, +Inf)
  806. math.copy_sign_f64(0, -1), // atan2(-1, +Inf)
  807. NaN, // atan2(+Pi, NaN)
  808. 3 * Pi / 4, // atan2(+Inf, -Inf)
  809. Pi / 2, // atan2(+Inf, -Pi)
  810. Pi / 2, // atan2(+Inf, +0)
  811. Pi / 2, // atan2(+Inf, +Pi)
  812. Pi / 4, // atan2(+Inf, +Inf)
  813. NaN, // atan2(+Inf, NaN)
  814. NaN, // atan2(NaN, NaN)
  815. }
  816. vfcbrt_sc := []f64{
  817. math.inf_f64(-1),
  818. math.copy_sign_f64(0, -1),
  819. 0,
  820. math.inf_f64(1),
  821. NaN,
  822. }
  823. cbrt_sc := []f64{
  824. math.inf_f64(-1),
  825. math.copy_sign_f64(0, -1),
  826. 0,
  827. math.inf_f64(1),
  828. NaN,
  829. }
  830. vfceil_sc := []f64{
  831. math.inf_f64(-1),
  832. math.copy_sign_f64(0, -1),
  833. 0,
  834. math.inf_f64(1),
  835. NaN,
  836. }
  837. ceil_sc := []f64{
  838. math.inf_f64(-1),
  839. math.copy_sign_f64(0, -1),
  840. 0,
  841. math.inf_f64(1),
  842. NaN,
  843. }
  844. vfcopysign_sc := []f64{
  845. math.inf_f64(-1),
  846. math.inf_f64(1),
  847. NaN,
  848. }
  849. copysign_sc := []f64{
  850. math.inf_f64(-1),
  851. math.inf_f64(-1),
  852. NaN,
  853. }
  854. vfcos_sc := []f64{
  855. math.inf_f64(-1),
  856. math.inf_f64(1),
  857. NaN,
  858. }
  859. cos_sc := []f64{
  860. NaN,
  861. NaN,
  862. NaN,
  863. }
  864. vfcosh_sc := []f64{
  865. math.inf_f64(-1),
  866. math.copy_sign_f64(0, -1),
  867. 0,
  868. math.inf_f64(1),
  869. NaN,
  870. }
  871. cosh_sc := []f64{
  872. math.inf_f64(1),
  873. 1,
  874. 1,
  875. math.inf_f64(1),
  876. NaN,
  877. }
  878. vfsin_sc := []f64{
  879. math.inf_f64(-1),
  880. math.copy_sign_f64(0, -1),
  881. 0,
  882. math.inf_f64(1),
  883. NaN,
  884. }
  885. sin_sc := []f64{
  886. NaN,
  887. math.copy_sign_f64(0, -1),
  888. 0,
  889. NaN,
  890. NaN,
  891. }
  892. vfsinh_sc := []f64{
  893. math.inf_f64(-1),
  894. math.copy_sign_f64(0, -1),
  895. 0,
  896. math.inf_f64(1),
  897. NaN,
  898. }
  899. sinh_sc := []f64{
  900. math.inf_f64(-1),
  901. math.copy_sign_f64(0, -1),
  902. 0,
  903. math.inf_f64(1),
  904. NaN,
  905. }
  906. vftanh_sc := []f64{
  907. math.inf_f64(-1),
  908. math.copy_sign_f64(0, -1),
  909. 0,
  910. math.inf_f64(1),
  911. NaN,
  912. }
  913. tanh_sc := []f64{
  914. -1,
  915. math.copy_sign_f64(0, -1),
  916. 0,
  917. 1,
  918. NaN,
  919. }
  920. tolerance :: proc(a, b, e: f64) -> bool {
  921. // Multiplying by e here can underflow denormal values to zero.
  922. // Check a==b so that at least if a and b are small and identical
  923. // we say they match.
  924. if a == b {
  925. return true
  926. }
  927. e := e
  928. d := a - b
  929. if d < 0 {
  930. d = -d
  931. }
  932. // note: b is correct (expected) value, a is actual value.
  933. // make error tolerance a fraction of b, not a.
  934. if b != 0 {
  935. e = e * b
  936. if e < 0 {
  937. e = -e
  938. }
  939. }
  940. return d < e
  941. }
  942. close :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
  943. ok := tolerance(a, b, 1e-9)
  944. // tc.expect(t, ok, fmt.tprintf("%.15g is not close to %.15g", a, b), loc)
  945. return ok
  946. }
  947. veryclose :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
  948. ok := tolerance(a, b, 4e-14)
  949. // tc.expect(t, ok, fmt.tprintf("%.15g is not veryclose to %.15g", a, b), loc)
  950. return ok
  951. }
  952. soclose :: proc(t: ^testing.T, a, b, e: f64, loc := #caller_location) -> bool {
  953. ok := tolerance(a, b, e)
  954. // tc.expect(t, ok, fmt.tprintf("%.15g is not soclose to %.15g", a, b), loc)
  955. return ok
  956. }
  957. alike :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
  958. ok := false
  959. switch {
  960. case math.is_nan(a) && math.is_nan(b):
  961. ok = true
  962. case a == b:
  963. ok = math.signbit(a) == math.signbit(b)
  964. }
  965. // tc.expect(t, ok, fmt.tprintf("%.15g is not alike to %.15g", a, b), loc)
  966. return ok
  967. }
  968. @test
  969. test_nan :: proc(t: ^testing.T) {
  970. float64 := NaN
  971. if float64 == float64 {
  972. tc.errorf(t, "NaN returns %.15g, expected NaN", float64)
  973. }
  974. float32 := f32(float64)
  975. if float32 == float32 {
  976. tc.errorf(t, "float32(NaN) is %.15g, expected NaN", float32)
  977. }
  978. }
  979. @test
  980. test_acos :: proc(t: ^testing.T) {
  981. for _, i in vf {
  982. a := vf[i] / 10
  983. if f := math.acos(a); !close(t, acos[i], f) {
  984. tc.errorf(t, "math.acos(%.15g) = %.15g, want %.15g", a, f, acos[i])
  985. }
  986. }
  987. for _, i in vfacos_sc {
  988. if f := math.acos(vfacos_sc[i]); !alike(t, acos_sc[i], f) {
  989. tc.errorf(t, "math.acos(%.15g) = %.15g, want %.15g", vfacos_sc[i], f, acos_sc[i])
  990. }
  991. }
  992. }
  993. @test
  994. test_acosh :: proc(t: ^testing.T) {
  995. for _, i in vf {
  996. a := 1 + abs(vf[i])
  997. if f := math.acosh(a); !veryclose(t, acosh[i], f) {
  998. tc.errorf(t, "math.acosh(%.15g) = %.15g, want %.15g", a, f, acosh[i])
  999. }
  1000. }
  1001. for _, i in vfacosh_sc {
  1002. if f := math.acosh(vfacosh_sc[i]); !alike(t, acosh_sc[i], f) {
  1003. tc.errorf(t, "math.acosh(%.15g) = %.15g, want %.15g", vfacosh_sc[i], f, acosh_sc[i])
  1004. }
  1005. }
  1006. }
  1007. @test
  1008. test_asin :: proc(t: ^testing.T) {
  1009. for _, i in vf {
  1010. a := vf[i] / 10
  1011. if f := math.asin(a); !veryclose(t, asin[i], f) {
  1012. tc.errorf(t, "math.asin(%.15g) = %.15g, want %.15g", a, f, asin[i])
  1013. }
  1014. }
  1015. for _, i in vfasin_sc {
  1016. if f := math.asin(vfasin_sc[i]); !alike(t, asin_sc[i], f) {
  1017. tc.errorf(t, "math.asin(%.15g) = %.15g, want %.15g", vfasin_sc[i], f, asin_sc[i])
  1018. }
  1019. }
  1020. }
  1021. @test
  1022. test_asinh :: proc(t: ^testing.T) {
  1023. for _, i in vf {
  1024. if f := math.asinh(vf[i]); !veryclose(t, asinh[i], f) {
  1025. tc.errorf(t, "math.asinh(%.15g) = %.15g, want %.15g", vf[i], f, asinh[i])
  1026. }
  1027. }
  1028. for _, i in vfasinh_sc {
  1029. if f := math.asinh(vfasinh_sc[i]); !alike(t, asinh_sc[i], f) {
  1030. tc.errorf(t, "math.asinh(%.15g) = %.15g, want %.15g", vfasinh_sc[i], f, asinh_sc[i])
  1031. }
  1032. }
  1033. }
  1034. @test
  1035. test_atan :: proc(t: ^testing.T) {
  1036. for _, i in vf {
  1037. if f := math.atan(vf[i]); !veryclose(t, atan[i], f) {
  1038. tc.errorf(t, "math.atan(%.15g) = %.15g, want %.15g", vf[i], f, atan[i])
  1039. }
  1040. }
  1041. for _, i in vfatan_sc {
  1042. if f := math.atan(vfatan_sc[i]); !alike(t, atan_sc[i], f) {
  1043. tc.errorf(t, "math.atan(%.15g) = %.15g, want %.15g", vfatan_sc[i], f, atan_sc[i])
  1044. }
  1045. }
  1046. }
  1047. @test
  1048. test_atanh :: proc(t: ^testing.T) {
  1049. for _, i in vf {
  1050. a := vf[i] / 10
  1051. if f := math.atanh(a); !veryclose(t, atanh[i], f) {
  1052. tc.errorf(t, "math.atanh(%.15g) = %.15g, want %.15g", a, f, atanh[i])
  1053. }
  1054. }
  1055. for _, i in vfatanh_sc {
  1056. if f := math.atanh(vfatanh_sc[i]); !alike(t, atanh_sc[i], f) {
  1057. tc.errorf(t, "math.atanh(%.15g) = %.15g, want %.15g", vfatanh_sc[i], f, atanh_sc[i])
  1058. }
  1059. }
  1060. }
  1061. @test
  1062. test_atan2 :: proc(t: ^testing.T) {
  1063. for _, i in vf {
  1064. if f := math.atan2(10, vf[i]); !veryclose(t, atan2[i], f) {
  1065. tc.errorf(t, "math.atan2(10, %.15g) = %.15g, want %.15g", vf[i], f, atan2[i])
  1066. }
  1067. }
  1068. for _, i in vfatan2_sc {
  1069. if f := math.atan2(vfatan2_sc[i][0], vfatan2_sc[i][1]); !alike(t, atan2_sc[i], f) {
  1070. tc.errorf(t, "math.atan2(%.15g, %.15g) = %.15g, want %.15g", vfatan2_sc[i][0], vfatan2_sc[i][1], f, atan2_sc[i])
  1071. }
  1072. }
  1073. }
  1074. @test
  1075. test_cos :: proc(t: ^testing.T) {
  1076. for _, i in vf {
  1077. if f := math.cos(vf[i]); !veryclose(t, cos[i], f) {
  1078. tc.errorf(t, "math.cos(%.15g) = %.15g, want %.15g", vf[i], f, cos[i])
  1079. }
  1080. }
  1081. for _, i in vfcos_sc {
  1082. if f := math.cos(vfcos_sc[i]); !alike(t, cos_sc[i], f) {
  1083. tc.errorf(t, "math.cos(%.15g) = %.15g, want %.15g", vfcos_sc[i], f, cos_sc[i])
  1084. }
  1085. }
  1086. }
  1087. @test
  1088. test_cosh :: proc(t: ^testing.T) {
  1089. for _, i in vf {
  1090. if f := math.cosh(vf[i]); !close(t, cosh[i], f) {
  1091. tc.errorf(t, "math.cosh(%.15g) = %.15g, want %.15g", vf[i], f, cosh[i])
  1092. }
  1093. }
  1094. for _, i in vfcosh_sc {
  1095. if f := math.cosh(vfcosh_sc[i]); !alike(t, cosh_sc[i], f) {
  1096. tc.errorf(t, "math.cosh(%.15g) = %.15g, want %.15g", vfcosh_sc[i], f, cosh_sc[i])
  1097. }
  1098. }
  1099. }
  1100. @test
  1101. test_sin :: proc(t: ^testing.T) {
  1102. for _, i in vf {
  1103. if f := math.sin(vf[i]); !veryclose(t, sin[i], f) {
  1104. tc.errorf(t, "math.sin(%.15g) = %.15g, want %.15g", vf[i], f, sin[i])
  1105. }
  1106. }
  1107. for _, i in vfsin_sc {
  1108. if f := math.sin(vfsin_sc[i]); !alike(t, sin_sc[i], f) {
  1109. tc.errorf(t, "math.sin(%.15g) = %.15g, want %.15g", vfsin_sc[i], f, sin_sc[i])
  1110. }
  1111. }
  1112. }
  1113. @test
  1114. test_sinh :: proc(t: ^testing.T) {
  1115. for _, i in vf {
  1116. if f := math.sinh(vf[i]); !close(t, sinh[i], f) {
  1117. tc.errorf(t, "math.sinh(%.15g) = %.15g, want %.15g", vf[i], f, sinh[i])
  1118. }
  1119. }
  1120. for _, i in vfsinh_sc {
  1121. if f := math.sinh(vfsinh_sc[i]); !alike(t, sinh_sc[i], f) {
  1122. tc.errorf(t, "math.sinh(%.15g) = %.15g, want %.15g", vfsinh_sc[i], f, sinh_sc[i])
  1123. }
  1124. }
  1125. }
  1126. @test
  1127. test_sqrt :: proc(t: ^testing.T) {
  1128. for _, i in vf {
  1129. a := abs(vf[i])
  1130. if f := math.sqrt(a); !veryclose(t, sqrt[i], f) {
  1131. tc.errorf(t, "math.sqrt(%.15g) = %.15g, want %.15g", a, f, sqrt[i])
  1132. }
  1133. }
  1134. }
  1135. @test
  1136. test_tan :: proc(t: ^testing.T) {
  1137. for _, i in vf {
  1138. if f := math.tan(vf[i]); !veryclose(t, tan[i], f) {
  1139. tc.errorf(t, "math.tan(%.15g) = %.15g, want %.15g", vf[i], f, tan[i])
  1140. }
  1141. }
  1142. // same special cases as Sin
  1143. for _, i in vfsin_sc {
  1144. if f := math.tan(vfsin_sc[i]); !alike(t, sin_sc[i], f) {
  1145. tc.errorf(t, "math.tan(%.15g) = %.15g, want %.15g", vfsin_sc[i], f, sin_sc[i])
  1146. }
  1147. }
  1148. }
  1149. @test
  1150. test_tanh :: proc(t: ^testing.T) {
  1151. for _, i in vf {
  1152. if f := math.tanh(vf[i]); !veryclose(t, tanh[i], f) {
  1153. tc.errorf(t, "math.tanh(%.15g) = %.15g, want %.15g", vf[i], f, tanh[i])
  1154. }
  1155. }
  1156. for _, i in vftanh_sc {
  1157. if f := math.tanh(vftanh_sc[i]); !alike(t, tanh_sc[i], f) {
  1158. tc.errorf(t, "math.tanh(%.15g) = %.15g, want %.15g", vftanh_sc[i], f, tanh_sc[i])
  1159. }
  1160. }
  1161. }
  1162. @test
  1163. test_large_cos :: proc(t: ^testing.T) {
  1164. large := f64(1e5 * Pi)
  1165. for _, i in vf {
  1166. f1 := cosLarge[i]
  1167. f2 := math.cos(vf[i] + large)
  1168. if !close(t, f1, f2) {
  1169. tc.errorf(t, "math.cos(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
  1170. }
  1171. }
  1172. }
  1173. @test
  1174. test_large_sin :: proc(t: ^testing.T) {
  1175. large := f64(1e5 * Pi)
  1176. for _, i in vf {
  1177. f1 := sinLarge[i]
  1178. f2 := math.sin(vf[i] + large)
  1179. if !close(t, f1, f2) {
  1180. tc.errorf(t, "math.sin(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
  1181. }
  1182. }
  1183. }
  1184. @test
  1185. test_large_tan :: proc(t: ^testing.T) {
  1186. large := f64(1e5 * Pi)
  1187. for _, i in vf {
  1188. f1 := tanLarge[i]
  1189. f2 := math.tan(vf[i] + large)
  1190. if !close(t, f1, f2) {
  1191. tc.errorf(t, "math.tan(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
  1192. }
  1193. }
  1194. }