1 | module math |
2 | |
3 | struct Fi { |
4 | f f64 |
5 | i int |
6 | } |
7 | |
8 | const ( |
9 | vf_ = [f64(4.9790119248836735e+00), 7.7388724745781045e+00, -2.7688005719200159e-01, |
10 | -5.0106036182710749e+00, 9.6362937071984173e+00, 2.9263772392439646e+00, |
11 | 5.2290834314593066e+00, 2.7279399104360102e+00, 1.8253080916808550e+00, |
12 | -8.6859247685756013e+00] |
13 | // The expected results below were computed by the high precision calculators |
14 | // at https://keisan.casio.com/. More exact input values (array vf_[], above) |
15 | // were obtained by printing them with "%.26f". The answers were calculated |
16 | // to 26 digits (by using the "Digit number" drop-down control of each |
17 | // calculator). |
18 | acos_ = [f64(1.0496193546107222142571536e+00), 6.8584012813664425171660692e-01, |
19 | 1.5984878714577160325521819e+00, 2.0956199361475859327461799e+00, |
20 | 2.7053008467824138592616927e-01, 1.2738121680361776018155625e+00, |
21 | 1.0205369421140629186287407e+00, 1.2945003481781246062157835e+00, |
22 | 1.3872364345374451433846657e+00, 2.6231510803970463967294145e+00] |
23 | acosh_ = [f64(2.4743347004159012494457618e+00), 2.8576385344292769649802701e+00, |
24 | 7.2796961502981066190593175e-01, 2.4796794418831451156471977e+00, |
25 | 3.0552020742306061857212962e+00, 2.044238592688586588942468e+00, |
26 | 2.5158701513104513595766636e+00, 1.99050839282411638174299e+00, |
27 | 1.6988625798424034227205445e+00, 2.9611454842470387925531875e+00] |
28 | asin_ = [f64(5.2117697218417440497416805e-01), 8.8495619865825236751471477e-01, |
29 | -2.769154466281941332086016e-02, -5.2482360935268931351485822e-01, |
30 | 1.3002662421166552333051524e+00, 2.9698415875871901741575922e-01, |
31 | 5.5025938468083370060258102e-01, 2.7629597861677201301553823e-01, |
32 | 1.83559892257451475846656e-01, -1.0523547536021497774980928e+00] |
33 | asinh_ = [f64(2.3083139124923523427628243e+00), 2.743551594301593620039021e+00, |
34 | -2.7345908534880091229413487e-01, -2.3145157644718338650499085e+00, |
35 | 2.9613652154015058521951083e+00, 1.7949041616585821933067568e+00, |
36 | 2.3564032905983506405561554e+00, 1.7287118790768438878045346e+00, |
37 | 1.3626658083714826013073193e+00, -2.8581483626513914445234004e+00] |
38 | atan_ = [f64(1.372590262129621651920085e+00), 1.442290609645298083020664e+00, |
39 | -2.7011324359471758245192595e-01, -1.3738077684543379452781531e+00, |
40 | 1.4673921193587666049154681e+00, 1.2415173565870168649117764e+00, |
41 | 1.3818396865615168979966498e+00, 1.2194305844639670701091426e+00, |
42 | 1.0696031952318783760193244e+00, -1.4561721938838084990898679e+00] |
43 | atanh_ = [f64(5.4651163712251938116878204e-01), 1.0299474112843111224914709e+00, |
44 | -2.7695084420740135145234906e-02, -5.5072096119207195480202529e-01, |
45 | 1.9943940993171843235906642e+00, 3.01448604578089708203017e-01, |
46 | 5.8033427206942188834370595e-01, 2.7987997499441511013958297e-01, |
47 | 1.8459947964298794318714228e-01, -1.3273186910532645867272502e+00] |
48 | atan2_ = [f64(1.1088291730037004444527075e+00), 9.1218183188715804018797795e-01, |
49 | 1.5984772603216203736068915e+00, 2.0352918654092086637227327e+00, |
50 | 8.0391819139044720267356014e-01, 1.2861075249894661588866752e+00, |
51 | 1.0889904479131695712182587e+00, 1.3044821793397925293797357e+00, |
52 | 1.3902530903455392306872261e+00, 2.2859857424479142655411058e+00] |
53 | ceil_ = [f64(5.0000000000000000e+00), 8.0000000000000000e+00, copysign(0, -1), |
54 | -5.0000000000000000e+00, 1.0000000000000000e+01, 3.0000000000000000e+00, |
55 | 6.0000000000000000e+00, 3.0000000000000000e+00, 2.0000000000000000e+00, |
56 | -8.0000000000000000e+00] |
57 | cos_ = [f64(2.634752140995199110787593e-01), 1.148551260848219865642039e-01, |
58 | 9.6191297325640768154550453e-01, 2.938141150061714816890637e-01, |
59 | -9.777138189897924126294461e-01, -9.7693041344303219127199518e-01, |
60 | 4.940088096948647263961162e-01, -9.1565869021018925545016502e-01, |
61 | -2.517729313893103197176091e-01, -7.39241351595676573201918e-01] |
62 | // Results for 100000 * pi + vf_[i] |
63 | cos_large_ = [f64(2.634752141185559426744e-01), 1.14855126055543100712e-01, |
64 | 9.61912973266488928113e-01, 2.9381411499556122552e-01, -9.777138189880161924641e-01, |
65 | -9.76930413445147608049e-01, 4.940088097314976789841e-01, -9.15658690217517835002e-01, |
66 | -2.51772931436786954751e-01, -7.3924135157173099849e-01] |
67 | cosh_ = [f64(7.2668796942212842775517446e+01), 1.1479413465659254502011135e+03, |
68 | 1.0385767908766418550935495e+00, 7.5000957789658051428857788e+01, |
69 | 7.655246669605357888468613e+03, 9.3567491758321272072888257e+00, |
70 | 9.331351599270605471131735e+01, 7.6833430994624643209296404e+00, |
71 | 3.1829371625150718153881164e+00, 2.9595059261916188501640911e+03] |
72 | exp_ = [f64(1.4533071302642137507696589e+02), 2.2958822575694449002537581e+03, |
73 | 7.5814542574851666582042306e-01, 6.6668778421791005061482264e-03, |
74 | 1.5310493273896033740861206e+04, 1.8659907517999328638667732e+01, |
75 | 1.8662167355098714543942057e+02, 1.5301332413189378961665788e+01, |
76 | 6.2047063430646876349125085e+00, 1.6894712385826521111610438e-04] |
77 | expm1_ = [f64(5.105047796122957327384770212e-02), 8.046199708567344080562675439e-02, |
78 | -2.764970978891639815187418703e-03, -4.8871434888875355394330300273e-02, |
79 | 1.0115864277221467777117227494e-01, 2.969616407795910726014621657e-02, |
80 | 5.368214487944892300914037972e-02, 2.765488851131274068067445335e-02, |
81 | 1.842068661871398836913874273e-02, -8.3193870863553801814961137573e-02] |
82 | expm1_large_ = [f64(4.2031418113550844e+21), 4.0690789717473863e+33, -0.9372627915981363e+00, |
83 | -1.0, 7.077694784145933e+41, 5.117936223839153e+12, 5.124137759001189e+22, |
84 | 7.03546003972584e+11, 8.456921800389698e+07, -1.0] |
85 | exp2_ = [f64(3.1537839463286288034313104e+01), 2.1361549283756232296144849e+02, |
86 | 8.2537402562185562902577219e-01, 3.1021158628740294833424229e-02, |
87 | 7.9581744110252191462569661e+02, 7.6019905892596359262696423e+00, |
88 | 3.7506882048388096973183084e+01, 6.6250893439173561733216375e+00, |
89 | 3.5438267900243941544605339e+00, 2.4281533133513300984289196e-03] |
90 | fabs_ = [f64(4.9790119248836735e+00), 7.7388724745781045e+00, 2.7688005719200159e-01, |
91 | 5.0106036182710749e+00, 9.6362937071984173e+00, 2.9263772392439646e+00, |
92 | 5.2290834314593066e+00, 2.7279399104360102e+00, 1.8253080916808550e+00, |
93 | 8.6859247685756013e+00] |
94 | floor_ = [f64(4.0000000000000000e+00), 7.0000000000000000e+00, -1.0000000000000000e+00, |
95 | -6.0000000000000000e+00, 9.0000000000000000e+00, 2.0000000000000000e+00, |
96 | 5.0000000000000000e+00, 2.0000000000000000e+00, 1.0000000000000000e+00, |
97 | -9.0000000000000000e+00] |
98 | fmod_ = [f64(4.197615023265299782906368e-02), 2.261127525421895434476482e+00, |
99 | 3.231794108794261433104108e-02, 4.989396381728925078391512e+00, |
100 | 3.637062928015826201999516e-01, 1.220868282268106064236690e+00, |
101 | 4.770916568540693347699744e+00, 1.816180268691969246219742e+00, |
102 | 8.734595415957246977711748e-01, 1.314075231424398637614104e+00] |
103 | frexp_ = [Fi{6.2237649061045918750e-01, 3}, Fi{9.6735905932226306250e-01, 3}, |
104 | Fi{-5.5376011438400318000e-01, -1}, Fi{-6.2632545228388436250e-01, 3}, |
105 | Fi{6.02268356699901081250e-01, 4}, Fi{7.3159430981099115000e-01, 2}, |
106 | Fi{6.5363542893241332500e-01, 3}, Fi{6.8198497760900255000e-01, 2}, |
107 | Fi{9.1265404584042750000e-01, 1}, Fi{-5.4287029803597508250e-01, 4}] |
108 | gamma_ = [f64(2.3254348370739963835386613898e+01), 2.991153837155317076427529816e+03, |
109 | -4.561154336726758060575129109e+00, 7.719403468842639065959210984e-01, |
110 | 1.6111876618855418534325755566e+05, 1.8706575145216421164173224946e+00, |
111 | 3.4082787447257502836734201635e+01, 1.579733951448952054898583387e+00, |
112 | 9.3834586598354592860187267089e-01, -2.093995902923148389186189429e-05] |
113 | log_gamma_ = [Fi{3.146492141244545774319734e+00, 1}, Fi{8.003414490659126375852113e+00, 1}, |
114 | Fi{1.517575735509779707488106e+00, -1}, Fi{-2.588480028182145853558748e-01, 1}, |
115 | Fi{1.1989897050205555002007985e+01, 1}, Fi{6.262899811091257519386906e-01, 1}, |
116 | Fi{3.5287924899091566764846037e+00, 1}, Fi{4.5725644770161182299423372e-01, 1}, |
117 | Fi{-6.363667087767961257654854e-02, 1}, Fi{-1.077385130910300066425564e+01, -1}] |
118 | log_ = [f64(1.605231462693062999102599e+00), 2.0462560018708770653153909e+00, |
119 | -1.2841708730962657801275038e+00, 1.6115563905281545116286206e+00, |
120 | 2.2655365644872016636317461e+00, 1.0737652208918379856272735e+00, |
121 | 1.6542360106073546632707956e+00, 1.0035467127723465801264487e+00, |
122 | 6.0174879014578057187016475e-01, 2.161703872847352815363655e+00] |
123 | logb_ = [f64(2.0000000000000000e+00), 2.0000000000000000e+00, -2.0000000000000000e+00, |
124 | 2.0000000000000000e+00, 3.0000000000000000e+00, 1.0000000000000000e+00, |
125 | 2.0000000000000000e+00, 1.0000000000000000e+00, 0.0000000000000000e+00, |
126 | 3.0000000000000000e+00] |
127 | log10_ = [f64(6.9714316642508290997617083e-01), 8.886776901739320576279124e-01, |
128 | -5.5770832400658929815908236e-01, 6.998900476822994346229723e-01, |
129 | 9.8391002850684232013281033e-01, 4.6633031029295153334285302e-01, |
130 | 7.1842557117242328821552533e-01, 4.3583479968917773161304553e-01, |
131 | 2.6133617905227038228626834e-01, 9.3881606348649405716214241e-01] |
132 | log1p_ = [f64(4.8590257759797794104158205e-02), 7.4540265965225865330849141e-02, |
133 | -2.7726407903942672823234024e-03, -5.1404917651627649094953380e-02, |
134 | 9.1998280672258624681335010e-02, 2.8843762576593352865894824e-02, |
135 | 5.0969534581863707268992645e-02, 2.6913947602193238458458594e-02, |
136 | 1.8088493239630770262045333e-02, -9.0865245631588989681559268e-02] |
137 | log2_ = [f64(2.3158594707062190618898251e+00), 2.9521233862883917703341018e+00, |
138 | -1.8526669502700329984917062e+00, 2.3249844127278861543568029e+00, |
139 | 3.268478366538305087466309e+00, 1.5491157592596970278166492e+00, |
140 | 2.3865580889631732407886495e+00, 1.447811865817085365540347e+00, |
141 | 8.6813999540425116282815557e-01, 3.118679457227342224364709e+00] |
142 | modf_ = [[f64(4.0000000000000000e+00), 9.7901192488367350108546816e-01], |
143 | [f64(7.0000000000000000e+00), 7.3887247457810456552351752e-01], |
144 | [f64(-0.0), -2.7688005719200159404635997e-01], |
145 | [f64(-5.0000000000000000e+00), |
146 | -1.060361827107492160848778e-02], |
147 | [f64(9.0000000000000000e+00), 6.3629370719841737980004837e-01], |
148 | [f64(2.0000000000000000e+00), 9.2637723924396464525443662e-01], |
149 | [f64(5.0000000000000000e+00), 2.2908343145930665230025625e-01], |
150 | [f64(2.0000000000000000e+00), 7.2793991043601025126008608e-01], |
151 | [f64(1.0000000000000000e+00), 8.2530809168085506044576505e-01], |
152 | [f64(-8.0000000000000000e+00), -6.8592476857560136238589621e-01]] |
153 | nextafter32_ = [4.979012489318848e+00, 7.738873004913330e+00, -2.768800258636475e-01, |
154 | -5.010602951049805e+00, 9.636294364929199e+00, 2.926377534866333e+00, 5.229084014892578e+00, |
155 | 2.727940082550049e+00, 1.825308203697205e+00, -8.685923576354980e+00] |
156 | nextafter64_ = [f64(4.97901192488367438926388786e+00), 7.73887247457810545370193722e+00, |
157 | -2.7688005719200153853520874e-01, -5.01060361827107403343006808e+00, |
158 | 9.63629370719841915615688777e+00, 2.92637723924396508934364647e+00, |
159 | 5.22908343145930754047867595e+00, 2.72793991043601069534929593e+00, |
160 | 1.82530809168085528249036997e+00, -8.68592476857559958602905681e+00] |
161 | pow_ = [f64(9.5282232631648411840742957e+04), 5.4811599352999901232411871e+07, |
162 | 5.2859121715894396531132279e-01, 9.7587991957286474464259698e-06, |
163 | 4.328064329346044846740467e+09, 8.4406761805034547437659092e+02, |
164 | 1.6946633276191194947742146e+05, 5.3449040147551939075312879e+02, |
165 | 6.688182138451414936380374e+01, 2.0609869004248742886827439e-09] |
166 | remainder_ = [f64(4.197615023265299782906368e-02), 2.261127525421895434476482e+00, |
167 | 3.231794108794261433104108e-02, -2.120723654214984321697556e-02, |
168 | 3.637062928015826201999516e-01, 1.220868282268106064236690e+00, |
169 | -4.581668629186133046005125e-01, -9.117596417440410050403443e-01, |
170 | 8.734595415957246977711748e-01, 1.314075231424398637614104e+00] |
171 | round_ = [f64(5), 8, copysign(0, -1), -5, 10, 3, 5, 3, 2, -9] |
172 | signbit_ = [false, false, true, true, false, false, false, false, false, true] |
173 | sin_ = [f64(-9.6466616586009283766724726e-01), 9.9338225271646545763467022e-01, |
174 | -2.7335587039794393342449301e-01, 9.5586257685042792878173752e-01, |
175 | -2.099421066779969164496634e-01, 2.135578780799860532750616e-01, |
176 | -8.694568971167362743327708e-01, 4.019566681155577786649878e-01, |
177 | 9.6778633541687993721617774e-01, -6.734405869050344734943028e-01] |
178 | // Results for 100000 * pi + vf_[i] |
179 | sin_large_ = [f64(-9.646661658548936063912e-01), 9.933822527198506903752e-01, |
180 | -2.7335587036246899796e-01, 9.55862576853689321268e-01, -2.099421066862688873691e-01, |
181 | 2.13557878070308981163e-01, -8.694568970959221300497e-01, 4.01956668098863248917e-01, |
182 | 9.67786335404528727927e-01, -6.7344058693131973066e-01] |
183 | sinh_ = [f64(7.2661916084208532301448439e+01), 1.1479409110035194500526446e+03, |
184 | -2.8043136512812518927312641e-01, -7.499429091181587232835164e+01, |
185 | 7.6552466042906758523925934e+03, 9.3031583421672014313789064e+00, |
186 | 9.330815755828109072810322e+01, 7.6179893137269146407361477e+00, |
187 | 3.021769180549615819524392e+00, -2.95950575724449499189888e+03] |
188 | sqrt_ = [f64(2.2313699659365484748756904e+00), 2.7818829009464263511285458e+00, |
189 | 5.2619393496314796848143251e-01, 2.2384377628763938724244104e+00, |
190 | 3.1042380236055381099288487e+00, 1.7106657298385224403917771e+00, |
191 | 2.286718922705479046148059e+00, 1.6516476350711159636222979e+00, |
192 | 1.3510396336454586262419247e+00, 2.9471892997524949215723329e+00] |
193 | tan_ = [f64(-3.661316565040227801781974e+00), 8.64900232648597589369854e+00, |
194 | -2.8417941955033612725238097e-01, 3.253290185974728640827156e+00, |
195 | 2.147275640380293804770778e-01, -2.18600910711067004921551e-01, |
196 | -1.760002817872367935518928e+00, -4.389808914752818126249079e-01, |
197 | -3.843885560201130679995041e+00, 9.10988793377685105753416e-01] |
198 | // Results for 100000 * pi + vf_[i] |
199 | tan_large_ = [f64(-3.66131656475596512705e+00), 8.6490023287202547927e+00, |
200 | -2.841794195104782406e-01, 3.2532901861033120983e+00, 2.14727564046880001365e-01, |
201 | -2.18600910700688062874e-01, -1.760002817699722747043e+00, -4.38980891453536115952e-01, |
202 | -3.84388555942723509071e+00, 9.1098879344275101051e-01] |
203 | tanh_ = [f64(9.9990531206936338549262119e-01), 9.9999962057085294197613294e-01, |
204 | -2.7001505097318677233756845e-01, -9.9991110943061718603541401e-01, |
205 | 9.9999999146798465745022007e-01, 9.9427249436125236705001048e-01, |
206 | 9.9994257600983138572705076e-01, 9.9149409509772875982054701e-01, |
207 | 9.4936501296239685514466577e-01, -9.9999994291374030946055701e-01] |
208 | trunc_ = [f64(4.0000000000000000e+00), 7.0000000000000000e+00, copysign(0, -1), |
209 | -5.0000000000000000e+00, 9.0000000000000000e+00, 2.0000000000000000e+00, |
210 | 5.0000000000000000e+00, 2.0000000000000000e+00, 1.0000000000000000e+00, |
211 | -8.0000000000000000e+00] |
212 | ) |
213 | |
214 | fn soclose(a f64, b f64, e_ f64) bool { |
215 | return tolerance(a, b, e_) |
216 | } |
217 | |
218 | fn test_nan() { |
219 | $if fast_math { |
220 | println('>> skipping ${@METHOD} with -fast-math') |
221 | return |
222 | } |
223 | // Note: these assertions do fail with `-cc gcc -cflags -ffast-math`: |
224 | nan_f64 := nan() |
225 | assert nan_f64 != nan_f64 |
226 | nan_f32 := f32(nan_f64) |
227 | assert nan_f32 != nan_f32 |
228 | } |
229 | |
230 | fn test_angle_diff() { |
231 | for pair in [ |
232 | [pi, pi_2, -pi_2], |
233 | [pi_2 * 3.0, pi_2, -pi], |
234 | [pi / 6.0, two_thirds * pi, pi_2], |
235 | ] { |
236 | assert angle_diff(pair[0], pair[1]) == pair[2] |
237 | } |
238 | } |
239 | |
240 | fn test_acos() { |
241 | for i := 0; i < math.vf_.len; i++ { |
242 | a := math.vf_[i] / 10 |
243 | f := acos(a) |
244 | assert soclose(math.acos_[i], f, 1e-7) |
245 | } |
246 | vfacos_sc_ := [-pi, 1, pi, nan()] |
247 | acos_sc_ := [nan(), 0, nan(), nan()] |
248 | for i := 0; i < vfacos_sc_.len; i++ { |
249 | f := acos(vfacos_sc_[i]) |
250 | assert alike(acos_sc_[i], f) |
251 | } |
252 | } |
253 | |
254 | fn test_acosh() { |
255 | for i := 0; i < math.vf_.len; i++ { |
256 | a := 1.0 + abs(math.vf_[i]) |
257 | f := acosh(a) |
258 | assert veryclose(math.acosh_[i], f) |
259 | } |
260 | vfacosh_sc_ := [inf(-1), 0.5, 1, inf(1), nan()] |
261 | acosh_sc_ := [nan(), nan(), 0, inf(1), nan()] |
262 | for i := 0; i < vfacosh_sc_.len; i++ { |
263 | f := acosh(vfacosh_sc_[i]) |
264 | assert alike(acosh_sc_[i], f) |
265 | } |
266 | } |
267 | |
268 | fn test_asin() { |
269 | for i := 0; i < math.vf_.len; i++ { |
270 | a := math.vf_[i] / 10 |
271 | f := asin(a) |
272 | assert veryclose(math.asin_[i], f) |
273 | } |
274 | vfasin_sc_ := [-pi, copysign(0, -1), 0, pi, nan()] |
275 | asin_sc_ := [nan(), copysign(0, -1), 0, nan(), nan()] |
276 | for i := 0; i < vfasin_sc_.len; i++ { |
277 | f := asin(vfasin_sc_[i]) |
278 | assert alike(asin_sc_[i], f) |
279 | } |
280 | } |
281 | |
282 | fn test_asinh() { |
283 | for i := 0; i < math.vf_.len; i++ { |
284 | f := asinh(math.vf_[i]) |
285 | assert veryclose(math.asinh_[i], f) |
286 | } |
287 | vfasinh_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
288 | asinh_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
289 | for i := 0; i < vfasinh_sc_.len; i++ { |
290 | f := asinh(vfasinh_sc_[i]) |
291 | assert alike(asinh_sc_[i], f) |
292 | } |
293 | } |
294 | |
295 | fn test_atan() { |
296 | for i := 0; i < math.vf_.len; i++ { |
297 | f := atan(math.vf_[i]) |
298 | assert veryclose(math.atan_[i], f) |
299 | } |
300 | vfatan_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
301 | atan_sc_ := [f64(-pi / 2), copysign(0, -1), 0, pi / 2, nan()] |
302 | for i := 0; i < vfatan_sc_.len; i++ { |
303 | f := atan(vfatan_sc_[i]) |
304 | assert alike(atan_sc_[i], f) |
305 | } |
306 | } |
307 | |
308 | fn test_atanh() { |
309 | for i := 0; i < math.vf_.len; i++ { |
310 | a := math.vf_[i] / 10 |
311 | f := atanh(a) |
312 | assert veryclose(math.atanh_[i], f) |
313 | } |
314 | vfatanh_sc_ := [inf(-1), -pi, -1, copysign(0, -1), 0, 1, pi, inf(1), |
315 | nan()] |
316 | atanh_sc_ := [nan(), nan(), inf(-1), copysign(0, -1), 0, inf(1), |
317 | nan(), nan(), nan()] |
318 | for i := 0; i < vfatanh_sc_.len; i++ { |
319 | f := atanh(vfatanh_sc_[i]) |
320 | assert alike(atanh_sc_[i], f) |
321 | } |
322 | } |
323 | |
324 | fn test_atan2() { |
325 | for i := 0; i < math.vf_.len; i++ { |
326 | f := atan2(10, math.vf_[i]) |
327 | assert veryclose(math.atan2_[i], f) |
328 | } |
329 | vfatan2_sc_ := [[inf(-1), inf(-1)], [inf(-1), -pi], [inf(-1), 0], |
330 | [inf(-1), pi], [inf(-1), inf(1)], [inf(-1), nan()], [-pi, inf(-1)], |
331 | [-pi, 0], [-pi, inf(1)], [-pi, nan()], [f64(-0.0), inf(-1)], |
332 | [f64(-0.0), -pi], [f64(-0.0), -0.0], [f64(-0.0), 0], [f64(-0.0), pi], |
333 | [f64(-0.0), inf(1)], [f64(-0.0), nan()], [f64(0), inf(-1)], |
334 | [f64(0), -pi], [f64(0), -0.0], [f64(0), 0], [f64(0), pi], |
335 | [f64(0), inf(1)], [f64(0), nan()], [pi, inf(-1)], [pi, 0], |
336 | [pi, inf(1)], [pi, nan()], [inf(1), inf(-1)], [inf(1), -pi], |
337 | [inf(1), 0], [inf(1), pi], [inf(1), inf(1)], [inf(1), nan()], |
338 | [nan(), nan()]] |
339 | atan2_sc_ := [f64(-3.0) * pi / 4.0, // atan2(-inf, -inf) |
340 | -pi / 2, // atan2(-inf, -pi) |
341 | -pi / 2, // atan2(-inf, +0) |
342 | -pi / 2, // atan2(-inf, pi) |
343 | -pi / 4, // atan2(-inf, +inf) |
344 | nan(), // atan2(-inf, nan) |
345 | -pi, // atan2(-pi, -inf) |
346 | -pi / 2, // atan2(-pi, +0) |
347 | -0.0, // atan2(-pi, inf) |
348 | nan(), // atan2(-pi, nan) |
349 | -pi, // atan2(-0, -inf) |
350 | -pi, // atan2(-0, -pi) |
351 | -pi, // atan2(-0, -0) |
352 | -0.0, // atan2(-0, +0) |
353 | -0.0, // atan2(-0, pi) |
354 | -0.0, // atan2(-0, +inf) |
355 | nan(), // atan2(-0, nan) |
356 | pi, // atan2(+0, -inf) |
357 | pi, // atan2(+0, -pi) |
358 | pi, // atan2(+0, -0) |
359 | 0, // atan2(+0, +0) |
360 | 0, // atan2(+0, pi) |
361 | 0, // atan2(+0, +inf) |
362 | nan(), // atan2(+0, nan) |
363 | pi, // atan2(pi, -inf) |
364 | pi / 2, // atan2(pi, +0) |
365 | 0, // atan2(pi, +inf) |
366 | nan(), // atan2(pi, nan) |
367 | 3.0 * pi / 4, // atan2(+inf, -inf) |
368 | pi / 2, // atan2(+inf, -pi) |
369 | pi / 2, // atan2(+inf, +0) |
370 | pi / 2, // atan2(+inf, pi) |
371 | pi / 4, // atan2(+inf, +inf) |
372 | nan(), // atan2(+inf, nan) |
373 | nan(), // atan2(nan, nan) |
374 | ] |
375 | for i := 0; i < vfatan2_sc_.len; i++ { |
376 | f := atan2(vfatan2_sc_[i][0], vfatan2_sc_[i][1]) |
377 | // Note: fails with `-cc gcc -cflags -ffast-math` |
378 | $if !fast_math { |
379 | assert alike(atan2_sc_[i], f), 'atan2_sc_[i]: ${atan2_sc_[i]:10}, f: ${f:10}' |
380 | } |
381 | } |
382 | } |
383 | |
384 | fn test_ceil() { |
385 | // for i := 0; i < vf_.len; i++ { |
386 | // f := ceil(vf_[i]) |
387 | // assert alike(ceil_[i], f) |
388 | // } |
389 | vfceil_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
390 | ceil_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
391 | for i := 0; i < vfceil_sc_.len; i++ { |
392 | f := ceil(vfceil_sc_[i]) |
393 | assert alike(ceil_sc_[i], f) |
394 | } |
395 | } |
396 | |
397 | fn test_cos() { |
398 | for i := 0; i < math.vf_.len; i++ { |
399 | f := cos(math.vf_[i]) |
400 | assert veryclose(math.cos_[i], f) |
401 | } |
402 | vfcos_sc_ := [inf(-1), inf(1), nan()] |
403 | cos_sc_ := [nan(), nan(), nan()] |
404 | for i := 0; i < vfcos_sc_.len; i++ { |
405 | f := cos(vfcos_sc_[i]) |
406 | assert alike(cos_sc_[i], f) |
407 | } |
408 | } |
409 | |
410 | fn test_cosh() { |
411 | for i := 0; i < math.vf_.len; i++ { |
412 | f := cosh(math.vf_[i]) |
413 | assert close(math.cosh_[i], f) |
414 | } |
415 | vfcosh_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
416 | cosh_sc_ := [inf(1), 1, 1, inf(1), nan()] |
417 | for i := 0; i < vfcosh_sc_.len; i++ { |
418 | f := cosh(vfcosh_sc_[i]) |
419 | assert alike(cosh_sc_[i], f) |
420 | } |
421 | } |
422 | |
423 | fn test_expm1() { |
424 | for i := 0; i < math.vf_.len; i++ { |
425 | a := math.vf_[i] / 100 |
426 | f := expm1(a) |
427 | assert veryclose(math.expm1_[i], f) |
428 | } |
429 | for i := 0; i < math.vf_.len; i++ { |
430 | a := math.vf_[i] * 10 |
431 | f := expm1(a) |
432 | assert close(math.expm1_large_[i], f) |
433 | } |
434 | // vfexpm1_sc_ := [f64(-710), copysign(0, -1), 0, 710, inf(1), nan()] |
435 | // expm1_sc_ := [f64(-1), copysign(0, -1), 0, inf(1), inf(1), nan()] |
436 | // for i := 0; i < vfexpm1_sc_.len; i++ { |
437 | // f := expm1(vfexpm1_sc_[i]) |
438 | // assert alike(expm1_sc_[i], f) |
439 | // } |
440 | } |
441 | |
442 | fn test_abs() { |
443 | for i := 0; i < math.vf_.len; i++ { |
444 | f := abs(math.vf_[i]) |
445 | assert math.fabs_[i] == f |
446 | } |
447 | } |
448 | |
449 | fn test_abs_zero() { |
450 | ret1 := abs(0) |
451 | println(ret1) |
452 | assert '${ret1}' == '0' |
453 | |
454 | ret2 := abs(0.0) |
455 | println(ret2) |
456 | assert '${ret2}' == '0.0' |
457 | } |
458 | |
459 | fn test_floor() { |
460 | for i := 0; i < math.vf_.len; i++ { |
461 | f := floor(math.vf_[i]) |
462 | assert alike(math.floor_[i], f) |
463 | } |
464 | vfceil_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
465 | ceil_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
466 | for i := 0; i < vfceil_sc_.len; i++ { |
467 | f := floor(vfceil_sc_[i]) |
468 | assert alike(ceil_sc_[i], f) |
469 | } |
470 | } |
471 | |
472 | fn test_max() { |
473 | for i := 0; i < math.vf_.len; i++ { |
474 | f := max(math.vf_[i], math.ceil_[i]) |
475 | assert math.ceil_[i] == f |
476 | } |
477 | } |
478 | |
479 | fn test_min() { |
480 | for i := 0; i < math.vf_.len; i++ { |
481 | f := min(math.vf_[i], math.floor_[i]) |
482 | assert math.floor_[i] == f |
483 | } |
484 | } |
485 | |
486 | fn test_clamp() { |
487 | assert clamp(2, 5, 10) == 5 |
488 | assert clamp(7, 5, 10) == 7 |
489 | assert clamp(15, 5, 10) == 10 |
490 | assert clamp(5, 5, 10) == 5 |
491 | assert clamp(10, 5, 10) == 10 |
492 | } |
493 | |
494 | fn test_signi() { |
495 | assert signi(inf(-1)) == -1 |
496 | assert signi(-72234878292.4586129) == -1 |
497 | assert signi(-10) == -1 |
498 | assert signi(-pi) == -1 |
499 | assert signi(-1) == -1 |
500 | assert signi(-0.000000000001) == -1 |
501 | assert signi(-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == -1 |
502 | assert signi(-0.0) == -1 |
503 | // |
504 | assert signi(inf(1)) == 1 |
505 | assert signi(72234878292.4586129) == 1 |
506 | assert signi(10) == 1 |
507 | assert signi(pi) == 1 |
508 | assert signi(1) == 1 |
509 | assert signi(0.000000000001) == 1 |
510 | assert signi(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == 1 |
511 | assert signi(0.0) == 1 |
512 | assert signi(nan()) == 1 |
513 | } |
514 | |
515 | fn test_sign() { |
516 | assert sign(inf(-1)) == -1.0 |
517 | assert sign(-72234878292.4586129) == -1.0 |
518 | assert sign(-10) == -1.0 |
519 | assert sign(-pi) == -1.0 |
520 | assert sign(-1) == -1.0 |
521 | assert sign(-0.000000000001) == -1.0 |
522 | assert sign(-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == -1.0 |
523 | assert sign(-0.0) == -1.0 |
524 | // |
525 | assert sign(inf(1)) == 1.0 |
526 | assert sign(72234878292.4586129) == 1 |
527 | assert sign(10) == 1.0 |
528 | assert sign(pi) == 1.0 |
529 | assert sign(1) == 1.0 |
530 | assert sign(0.000000000001) == 1.0 |
531 | assert sign(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == 1.0 |
532 | assert sign(0.0) == 1.0 |
533 | $if !fast_math { |
534 | // Note: these assertions fail with `-cc gcc -cflags -ffast-math`: |
535 | assert is_nan(sign(nan())), '${sign(nan()):20}, ${nan():20}' |
536 | assert is_nan(sign(-nan())), '${sign(-nan()):20}, ${-nan():20}' |
537 | } |
538 | } |
539 | |
540 | fn test_mod() { |
541 | for i := 0; i < math.vf_.len; i++ { |
542 | f := mod(10, math.vf_[i]) |
543 | assert math.fmod_[i] == f |
544 | } |
545 | // verify precision of result for extreme inputs |
546 | f := mod(5.9790119248836734e+200, 1.1258465975523544) |
547 | assert (0.6447968302508578) == f |
548 | } |
549 | |
550 | fn test_cbrt() { |
551 | cbrts := [2.0, 10, 56] |
552 | for idx, i in [8.0, 1000, 175_616] { |
553 | assert cbrt(i) == cbrts[idx] |
554 | } |
555 | } |
556 | |
557 | fn test_exp() { |
558 | for i := 0; i < math.vf_.len; i++ { |
559 | f := exp(math.vf_[i]) |
560 | assert close(math.exp_[i], f), 'math.exp_[i]: ${math.exp_[i]:10}, ${f64_bits(math.exp_[i]):12} | f: ${f}, ${f64_bits(f):12}' |
561 | } |
562 | vfexp_sc_ := [inf(-1), -2000, 2000, inf(1), nan(), // smallest f64 that overflows Exp(x) |
563 | 7.097827128933841e+02, 1.48852223e+09, 1.4885222e+09, 1, // near zero |
564 | 3.725290298461915e-09, -740, // denormal |
565 | ] |
566 | exp_sc_ := [f64(0), 0, inf(1), inf(1), nan(), inf(1), inf(1), |
567 | inf(1), 2.718281828459045, 1.0000000037252903, 4.2e-322] |
568 | for i := 0; i < vfexp_sc_.len; i++ { |
569 | f := exp(vfexp_sc_[i]) |
570 | assert close(exp_sc_[i], f) || alike(exp_sc_[i], f), 'exp_sc_[i]: ${exp_sc_[i]:10}, ${f64_bits(exp_sc_[i]):12}, f: ${f:10}, ${f64_bits(f):12}' |
571 | } |
572 | } |
573 | |
574 | fn test_exp2() { |
575 | for i := 0; i < math.vf_.len; i++ { |
576 | f := exp2(math.vf_[i]) |
577 | assert soclose(math.exp2_[i], f, 1e-9) |
578 | } |
579 | vfexp2_sc_ := [f64(-2000), 2000, inf(1), nan(), // smallest f64 that overflows Exp2(x) |
580 | 1024, -1.07399999999999e+03, // near underflow |
581 | 3.725290298461915e-09, // near zero |
582 | ] |
583 | exp2_sc_ := [f64(0), inf(1), inf(1), nan(), inf(1), 5e-324, 1.0000000025821745] |
584 | for i := 0; i < vfexp2_sc_.len; i++ { |
585 | f := exp2(vfexp2_sc_[i]) |
586 | assert alike(exp2_sc_[i], f) |
587 | } |
588 | for n := -1074; n < 1024; n++ { |
589 | f := exp2(f64(n)) |
590 | vf := ldexp(1, n) |
591 | assert veryclose(f, vf) |
592 | } |
593 | } |
594 | |
595 | fn test_frexp() { |
596 | for i := 0; i < math.vf_.len; i++ { |
597 | f, j := frexp(math.vf_[i]) |
598 | assert veryclose(math.frexp_[i].f, f) || math.frexp_[i].i != j |
599 | } |
600 | // vffrexp_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
601 | // frexp_sc_ := [Fi{inf(-1), 0}, Fi{copysign(0, -1), 0}, Fi{0, 0}, |
602 | // Fi{inf(1), 0}, Fi{nan(), 0}] |
603 | // for i := 0; i < vffrexp_sc_.len; i++ { |
604 | // f, j := frexp(vffrexp_sc_[i]) |
605 | // assert alike(frexp_sc_[i].f, f) || frexp_sc_[i].i != j |
606 | // } |
607 | } |
608 | |
609 | fn test_gamma() { |
610 | vfgamma_ := [[inf(1), inf(1)], [inf(-1), nan()], [f64(0), inf(1)], |
611 | [f64(-0.0), inf(-1)], [nan(), nan()], [f64(-1), nan()], |
612 | [f64(-2), nan()], [f64(-3), nan()], [f64(-1e+16), nan()], |
613 | [f64(-1e+300), nan()], [f64(1.7e+308), inf(1)], // Test inputs inspi_red by Python test suite |
614 | |
615 | // Outputs computed at high precision by PARI/GP. |
616 | // If recomputing table entries), be careful to use |
617 | // high-precision (%.1000g) formatting of the f64 inputs. |
618 | // For example), -2.0000000000000004 is the f64 with exact value |
619 | //-2.00000000000000044408920985626161695), and |
620 | // gamma(-2.0000000000000004) = -1249999999999999.5386078562728167651513), while |
621 | // gamma(-2.00000000000000044408920985626161695) = -1125899906826907.2044875028130093136826. |
622 | // Thus the table lists -1.1258999068426235e+15 as the answer. |
623 | [f64(0.5), 1.772453850905516], [f64(1.5), 0.886226925452758], |
624 | [f64(2.5), 1.329340388179137], [f64(3.5), 3.3233509704478426], |
625 | [f64(-0.5), -3.544907701811032], [f64(-1.5), 2.363271801207355], |
626 | [f64(-2.5), -0.9453087204829419], [f64(-3.5), 0.2700882058522691], |
627 | [f64(0.1), 9.51350769866873], [f64(0.01), 99.4325851191506], |
628 | [f64(1e-08), 9.999999942278434e+07], [f64(1e-16), 1e+16], |
629 | [f64(0.001), 999.4237724845955], [f64(1e-16), 1e+16], |
630 | [f64(1e-308), 1e+308], [f64(5.6e-309), 1.7857142857142864e+308], |
631 | [f64(5.5e-309), inf(1)], [f64(1e-309), inf(1)], [f64(1e-323), inf(1)], |
632 | [f64(5e-324), inf(1)], [f64(-0.1), -10.686287021193193], |
633 | [f64(-0.01), -100.58719796441078], [f64(-1e-08), -1.0000000057721567e+08], |
634 | [f64(-1e-16), -1e+16], [f64(-0.001), -1000.5782056293586], |
635 | [f64(-1e-16), -1e+16], [f64(-1e-308), -1e+308], [f64(-5.6e-309), -1.7857142857142864e+308], |
636 | [f64(-5.5e-309), inf(-1)], [f64(-1e-309), inf(-1)], [f64(-1e-323), inf(-1)], |
637 | [f64(-5e-324), inf(-1)], [f64(-0.9999999999999999), -9.007199254740992e+15], |
638 | [f64(-1.0000000000000002), 4.5035996273704955e+15], |
639 | [f64(-1.9999999999999998), |
640 | 2.2517998136852485e+15], |
641 | [f64(-2.0000000000000004), -1.1258999068426235e+15], |
642 | [f64(-100.00000000000001), |
643 | -7.540083334883109e-145], |
644 | [f64(-99.99999999999999), 7.540083334884096e-145], [f64(17), 2.0922789888e+13], |
645 | [f64(171), 7.257415615307999e+306], [f64(171.6), 1.5858969096672565e+308], |
646 | [f64(171.624), 1.7942117599248104e+308], [f64(171.625), inf(1)], |
647 | [f64(172), inf(1)], [f64(2000), inf(1)], [f64(-100.5), -3.3536908198076787e-159], |
648 | [f64(-160.5), -5.255546447007829e-286], [f64(-170.5), -3.3127395215386074e-308], |
649 | [f64(-171.5), 1.9316265431712e-310], [f64(-176.5), -1.196e-321], |
650 | [f64(-177.5), 5e-324], [f64(-178.5), -0.0], [f64(-179.5), 0], |
651 | [f64(-201.0001), 0], [f64(-202.9999), -0.0], [f64(-1000.5), -0.0], |
652 | [f64(-1.0000000003e+09), -0.0], [f64(-4.5035996273704955e+15), 0], |
653 | [f64(-63.349078729022985), 4.177797167776188e-88], |
654 | [f64(-127.45117632943295), |
655 | 1.183111089623681e-214]] |
656 | _ := vfgamma_[0][0] |
657 | // @todo: Figure out solution for C backend |
658 | // for i := 0; i < math.vf_.len; i++ { |
659 | // f := gamma(math.vf_[i]) |
660 | // assert veryclose(math.gamma_[i], f) |
661 | // } |
662 | // for _, g in vfgamma_ { |
663 | // f := gamma(g[0]) |
664 | // if is_nan(g[1]) || is_inf(g[1], 0) || g[1] == 0 || f == 0 { |
665 | // assert alike(g[1], f) |
666 | // } else if g[0] > -50 && g[0] <= 171 { |
667 | // assert veryclose(g[1], f) |
668 | // } else { |
669 | // assert soclose(g[1], f, 1e-9) |
670 | // } |
671 | // } |
672 | } |
673 | |
674 | fn test_hypot() { |
675 | for i := 0; i < math.vf_.len; i++ { |
676 | a := abs(1e+200 * math.tanh_[i] * sqrt(2.0)) |
677 | f := hypot(1e+200 * math.tanh_[i], 1e+200 * math.tanh_[i]) |
678 | assert veryclose(a, f) |
679 | } |
680 | vfhypot_sc_ := [[inf(-1), inf(-1)], [inf(-1), 0], [inf(-1), |
681 | inf(1)], |
682 | [inf(-1), nan()], [f64(-0.0), -0.0], [f64(-0.0), 0], [f64(0), -0.0], |
683 | [f64(0), 0], [f64(0), inf(-1)], [f64(0), inf(1)], [f64(0), nan()], |
684 | [inf(1), inf(-1)], [inf(1), 0], [inf(1), inf(1)], [inf(1), |
685 | nan()], |
686 | [nan(), inf(-1)], [nan(), 0], [nan(), inf(1)], [nan(), |
687 | nan()]] |
688 | hypot_sc_ := [inf(1), inf(1), inf(1), inf(1), 0, 0, 0, 0, inf(1), |
689 | inf(1), nan(), inf(1), inf(1), inf(1), inf(1), inf(1), |
690 | nan(), inf(1), nan()] |
691 | for i := 0; i < vfhypot_sc_.len; i++ { |
692 | f := hypot(vfhypot_sc_[i][0], vfhypot_sc_[i][1]) |
693 | assert alike(hypot_sc_[i], f) |
694 | } |
695 | } |
696 | |
697 | fn test_ldexp() { |
698 | for i := 0; i < math.vf_.len; i++ { |
699 | f := ldexp(math.frexp_[i].f, math.frexp_[i].i) |
700 | assert veryclose(math.vf_[i], f) |
701 | } |
702 | vffrexp_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
703 | frexp_sc_ := [Fi{inf(-1), 0}, Fi{copysign(0, -1), 0}, Fi{0, 0}, |
704 | Fi{inf(1), 0}, Fi{nan(), 0}] |
705 | for i := 0; i < vffrexp_sc_.len; i++ { |
706 | f := ldexp(frexp_sc_[i].f, frexp_sc_[i].i) |
707 | assert alike(vffrexp_sc_[i], f) |
708 | } |
709 | vfldexp_sc_ := [Fi{0, 0}, Fi{0, -1075}, Fi{0, 1024}, Fi{copysign(0, -1), 0}, |
710 | Fi{copysign(0, -1), -1075}, Fi{copysign(0, -1), 1024}, |
711 | Fi{inf(1), 0}, Fi{inf(1), -1024}, Fi{inf(-1), 0}, Fi{inf(-1), -1024}, |
712 | Fi{nan(), -1024}, Fi{10, 1 << (u64(sizeof(int) - 1) * 8)}, |
713 | Fi{10, -(1 << (u64(sizeof(int) - 1) * 8))}] |
714 | ldexp_sc_ := [f64(0), 0, 0, copysign(0, -1), copysign(0, -1), |
715 | copysign(0, -1), inf(1), inf(1), inf(-1), inf(-1), nan(), |
716 | inf(1), 0] |
717 | for i := 0; i < vfldexp_sc_.len; i++ { |
718 | f := ldexp(vfldexp_sc_[i].f, vfldexp_sc_[i].i) |
719 | assert alike(ldexp_sc_[i], f) |
720 | } |
721 | } |
722 | |
723 | fn test_log_gamma() { |
724 | for i := 0; i < math.vf_.len; i++ { |
725 | f, s := log_gamma_sign(math.vf_[i]) |
726 | assert soclose(math.log_gamma_[i].f, f, 1e-6) && math.log_gamma_[i].i == s |
727 | } |
728 | // vflog_gamma_sc_ := [inf(-1), -3, 0, 1, 2, inf(1), nan()] |
729 | // log_gamma_sc_ := [Fi{inf(-1), 1}, Fi{inf(1), 1}, Fi{inf(1), 1}, |
730 | // Fi{0, 1}, Fi{0, 1}, Fi{inf(1), 1}, Fi{nan(), 1}] |
731 | // for i := 0; i < vflog_gamma_sc_.len; i++ { |
732 | // f, s := log_gamma_sign(vflog_gamma_sc_[i]) |
733 | // assert alike(log_gamma_sc_[i].f, f) && log_gamma_sc_[i].i == s |
734 | // } |
735 | } |
736 | |
737 | fn test_log() { |
738 | for i := 0; i < math.vf_.len; i++ { |
739 | a := abs(math.vf_[i]) |
740 | f := log(a) |
741 | assert math.log_[i] == f |
742 | } |
743 | vflog_sc_ := [inf(-1), -pi, copysign(0, -1), 0, 1, inf(1), |
744 | nan()] |
745 | log_sc_ := [nan(), nan(), inf(-1), inf(-1), 0, inf(1), nan()] |
746 | f := log(10) |
747 | assert f == ln10 |
748 | for i := 0; i < vflog_sc_.len; i++ { |
749 | g := log(vflog_sc_[i]) |
750 | assert alike(log_sc_[i], g) |
751 | } |
752 | } |
753 | |
754 | fn test_log10() { |
755 | for i := 0; i < math.vf_.len; i++ { |
756 | a := abs(math.vf_[i]) |
757 | f := log10(a) |
758 | assert veryclose(math.log10_[i], f) |
759 | } |
760 | vflog_sc_ := [inf(-1), -pi, copysign(0, -1), 0, 1, inf(1), |
761 | nan()] |
762 | log_sc_ := [nan(), nan(), inf(-1), inf(-1), 0, inf(1), nan()] |
763 | for i := 0; i < vflog_sc_.len; i++ { |
764 | f := log10(vflog_sc_[i]) |
765 | assert alike(log_sc_[i], f) |
766 | } |
767 | } |
768 | |
769 | fn test_pow() { |
770 | for i := 0; i < math.vf_.len; i++ { |
771 | f := pow(10, math.vf_[i]) |
772 | assert close(math.pow_[i], f) |
773 | } |
774 | vfpow_sc_ := [[inf(-1), -pi], [inf(-1), -3], [inf(-1), -0.0], |
775 | [inf(-1), 0], [inf(-1), 1], [inf(-1), 3], [inf(-1), pi], |
776 | [inf(-1), 0.5], [inf(-1), nan()], [-pi, inf(-1)], [-pi, -pi], |
777 | [-pi, -0.0], [-pi, 0], [-pi, 1], [-pi, pi], [-pi, inf(1)], |
778 | [-pi, nan()], [f64(-1), inf(-1)], [f64(-1), inf(1)], [f64(-1), nan()], |
779 | [f64(-1 / 2), inf(-1)], [f64(-1 / 2), inf(1)], [f64(-0.0), inf(-1)], |
780 | [f64(-0.0), -pi], [f64(-0.0), -0.5], [f64(-0.0), -3], |
781 | [f64(-0.0), 3], [f64(-0.0), pi], [f64(-0.0), 0.5], [f64(-0.0), inf(1)], |
782 | [f64(0), inf(-1)], [f64(0), -pi], [f64(0), -3], [f64(0), -0.0], |
783 | [f64(0), 0], [f64(0), 3], [f64(0), pi], [f64(0), inf(1)], |
784 | [f64(0), nan()], [f64(1 / 2), inf(-1)], [f64(1 / 2), inf(1)], |
785 | [f64(1), inf(-1)], [f64(1), inf(1)], [f64(1), nan()], |
786 | [pi, inf(-1)], [pi, -0.0], [pi, 0], [pi, 1], [pi, inf(1)], |
787 | [pi, nan()], [inf(1), -pi], [inf(1), -0.0], [inf(1), 0], |
788 | [inf(1), 1], [inf(1), pi], [inf(1), nan()], [nan(), -pi], |
789 | [nan(), -0.0], [nan(), 0], [nan(), 1], [nan(), pi], [nan(), |
790 | nan()], |
791 | [5.0, 2.0], [5.0, 3.0], [5.0, 10.0], [5.0, -2.0], [-5.0, -1.0], |
792 | [-5.0, -2.0], [-5.0, -3.0]] |
793 | pow_sc_ := [f64(0), // pow(-inf, -pi) |
794 | -0.0, // pow(-inf, -3) |
795 | 1, // pow(-inf, -0) |
796 | 1, // pow(-inf, +0) |
797 | inf(-1), // pow(-inf, 1) |
798 | inf(-1), // pow(-inf, 3) |
799 | inf(1), // pow(-inf, pi) |
800 | inf(1), // pow(-inf, 0.5) |
801 | nan(), // pow(-inf, nan) |
802 | 0, // pow(-pi, -inf) |
803 | nan(), // pow(-pi, -pi) |
804 | 1, // pow(-pi, -0) |
805 | 1, // pow(-pi, +0) |
806 | -pi, // pow(-pi, 1) |
807 | nan(), // pow(-pi, pi) |
808 | inf(1), // pow(-pi, +inf) |
809 | nan(), // pow(-pi, nan) |
810 | 1, // pow(-1, -inf) IEEE 754-2008 |
811 | 1, // pow(-1, +inf) IEEE 754-2008 |
812 | nan(), // pow(-1, nan) |
813 | inf(1), // pow(-1/2, -inf) |
814 | 0, // pow(-1/2, +inf) |
815 | inf(1), // pow(-0, -inf) |
816 | inf(1), // pow(-0, -pi) |
817 | inf(1), // pow(-0, -0.5) |
818 | inf(-1), // pow(-0, -3) IEEE 754-2008 |
819 | -0.0, // pow(-0, 3) IEEE 754-2008 |
820 | 0, // pow(-0, pi) |
821 | 0, // pow(-0, 0.5) |
822 | 0, // pow(-0, +inf) |
823 | inf(1), // pow(+0, -inf) |
824 | inf(1), // pow(+0, -pi) |
825 | inf(1), // pow(+0, -3) |
826 | 1, // pow(+0, -0) |
827 | 1, // pow(+0, +0) |
828 | 0, // pow(+0, 3) |
829 | 0, // pow(+0, pi) |
830 | 0, // pow(+0, +inf) |
831 | nan(), // pow(+0, nan) |
832 | inf(1), // pow(1/2, -inf) |
833 | 0, // pow(1/2, +inf) |
834 | 1, // pow(1, -inf) IEEE 754-2008 |
835 | 1, // pow(1, +inf) IEEE 754-2008 |
836 | 1, // pow(1, nan) IEEE 754-2008 |
837 | 0, // pow(pi, -inf) |
838 | 1, // pow(pi, -0) |
839 | 1, // pow(pi, +0) |
840 | pi, // pow(pi, 1) |
841 | inf(1), // pow(pi, +inf) |
842 | nan(), // pow(pi, nan) |
843 | 0, // pow(+inf, -pi) |
844 | 1, // pow(+inf, -0) |
845 | 1, // pow(+inf, +0) |
846 | inf(1), // pow(+inf, 1) |
847 | inf(1), // pow(+inf, pi) |
848 | nan(), // pow(+inf, nan) |
849 | nan(), // pow(nan, -pi) |
850 | 1, // pow(nan, -0) |
851 | 1, // pow(nan, +0) |
852 | nan(), // pow(nan, 1) |
853 | nan(), // pow(nan, pi) |
854 | nan(), // pow(nan, nan) |
855 | 25, // pow(5, 2) => 5 * 5 |
856 | 125, // pow(5, 3) => 5 * 5 * 5 |
857 | 9765625, // pow(5, 10) |
858 | 0.04, // pow(5, -2) |
859 | -0.2, // pow(-5, -1) |
860 | 0.04, // pow(-5, -2) |
861 | -0.008, // pow(-5, -3) |
862 | ] |
863 | for i := 0; i < vfpow_sc_.len; i++ { |
864 | f := pow(vfpow_sc_[i][0], vfpow_sc_[i][1]) |
865 | // close() below is needed, otherwise gcc on windows fails with: |
866 | // i: 65 | vfpow_sc_[i][0]: 5, vfpow_sc_[i][1]: -2 | pow_sc_[65] = 0.04, f = 0.04000000000000001 |
867 | assert close(pow_sc_[i], f) || alike(pow_sc_[i], f), 'i: ${i:3} | vfpow_sc_[i][0]: ${vfpow_sc_[i][0]:10}, vfpow_sc_[i][1]: ${vfpow_sc_[i][1]:10} | pow_sc_[${i}] = ${pow_sc_[i]}, f = ${f}' |
868 | } |
869 | } |
870 | |
871 | fn test_round() { |
872 | for i := 0; i < math.vf_.len; i++ { |
873 | f := round(math.vf_[i]) |
874 | assert alike(math.round_[i], f) |
875 | } |
876 | vfround_sc_ := [[f64(0), 0], [nan(), nan()], [inf(1), inf(1)]] |
877 | // vfround_even_sc_ := [[f64(0), 0], [f64(1.390671161567e-309), 0], // denormal |
878 | // [f64(0.49999999999999994), 0], // 0.5-epsilon [f64(0.5), 0], |
879 | // [f64(0.5000000000000001), 1], // 0.5+epsilon [f64(-1.5), -2], |
880 | // [f64(-2.5), -2], [nan(), nan()], [inf(1), inf(1)], |
881 | // [f64(2251799813685249.5), 2251799813685250], |
882 | // // 1 bit fractian [f64(2251799813685250.5), 2251799813685250], |
883 | // [f64(4503599627370495.5), 4503599627370496], // 1 bit fraction, rounding to 0 bit fractian |
884 | // [f64(4503599627370497), 4503599627370497], // large integer |
885 | // ] |
886 | for i := 0; i < vfround_sc_.len; i++ { |
887 | f := round(vfround_sc_[i][0]) |
888 | assert alike(vfround_sc_[i][1], f) |
889 | } |
890 | } |
891 | |
892 | fn fn_test_round_sig() { |
893 | assert round_sig(4.3239437319748394, -1) == 4.3239437319748394 |
894 | assert round_sig(4.3239437319748394, 0) == 4.0000000000000000 |
895 | assert round_sig(4.3239437319748394, 1) == 4.3000000000000000 |
896 | assert round_sig(4.3239437319748394, 2) == 4.3200000000000000 |
897 | assert round_sig(4.3239437319748394, 3) == 4.3240000000000000 |
898 | assert round_sig(4.3239437319748394, 6) == 4.3239440000000000 |
899 | assert round_sig(4.3239437319748394, 12) == 4.323943731975 |
900 | assert round_sig(4.3239437319748394, 17) == 4.3239437319748394 |
901 | } |
902 | |
903 | fn test_sin() { |
904 | for i := 0; i < math.vf_.len; i++ { |
905 | f := sin(math.vf_[i]) |
906 | assert veryclose(math.sin_[i], f) |
907 | } |
908 | vfsin_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
909 | sin_sc_ := [nan(), copysign(0, -1), 0, nan(), nan()] |
910 | for i := 0; i < vfsin_sc_.len; i++ { |
911 | f := sin(vfsin_sc_[i]) |
912 | assert alike(sin_sc_[i], f) |
913 | } |
914 | } |
915 | |
916 | fn test_sincos() { |
917 | for i := 0; i < math.vf_.len; i++ { |
918 | f, g := sincos(math.vf_[i]) |
919 | assert veryclose(math.sin_[i], f) |
920 | assert veryclose(math.cos_[i], g) |
921 | } |
922 | vfsin_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
923 | sin_sc_ := [nan(), copysign(0, -1), 0, nan(), nan()] |
924 | for i := 0; i < vfsin_sc_.len; i++ { |
925 | f, _ := sincos(vfsin_sc_[i]) |
926 | assert alike(sin_sc_[i], f) |
927 | } |
928 | vfcos_sc_ := [inf(-1), inf(1), nan()] |
929 | cos_sc_ := [nan(), nan(), nan()] |
930 | for i := 0; i < vfcos_sc_.len; i++ { |
931 | _, f := sincos(vfcos_sc_[i]) |
932 | assert alike(cos_sc_[i], f) |
933 | } |
934 | } |
935 | |
936 | fn test_sinh() { |
937 | for i := 0; i < math.vf_.len; i++ { |
938 | f := sinh(math.vf_[i]) |
939 | assert close(math.sinh_[i], f) |
940 | } |
941 | vfsinh_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
942 | sinh_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
943 | for i := 0; i < vfsinh_sc_.len; i++ { |
944 | f := sinh(vfsinh_sc_[i]) |
945 | assert alike(sinh_sc_[i], f) |
946 | } |
947 | } |
948 | |
949 | fn test_sqrt() { |
950 | for i := 0; i < math.vf_.len; i++ { |
951 | mut a := abs(math.vf_[i]) |
952 | mut f := sqrt(a) |
953 | assert veryclose(math.sqrt_[i], f) |
954 | a = abs(math.vf_[i]) |
955 | f = sqrt(a) |
956 | assert veryclose(math.sqrt_[i], f) |
957 | } |
958 | vfsqrt_sc_ := [inf(-1), -pi, copysign(0, -1), 0, inf(1), nan()] |
959 | sqrt_sc_ := [nan(), nan(), copysign(0, -1), 0, inf(1), nan()] |
960 | for i := 0; i < vfsqrt_sc_.len; i++ { |
961 | mut f := sqrt(vfsqrt_sc_[i]) |
962 | assert alike(sqrt_sc_[i], f) |
963 | f = sqrt(vfsqrt_sc_[i]) |
964 | assert alike(sqrt_sc_[i], f) |
965 | } |
966 | } |
967 | |
968 | fn test_tan() { |
969 | for i := 0; i < math.vf_.len; i++ { |
970 | f := tan(math.vf_[i]) |
971 | assert veryclose(math.tan_[i], f) |
972 | } |
973 | vfsin_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
974 | sin_sc_ := [nan(), copysign(0, -1), 0, nan(), nan()] |
975 | // same special cases as sin |
976 | for i := 0; i < vfsin_sc_.len; i++ { |
977 | f := tan(vfsin_sc_[i]) |
978 | assert alike(sin_sc_[i], f) |
979 | } |
980 | } |
981 | |
982 | fn test_tanh() { |
983 | for i := 0; i < math.vf_.len; i++ { |
984 | f := tanh(math.vf_[i]) |
985 | assert veryclose(math.tanh_[i], f) |
986 | } |
987 | vftanh_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
988 | tanh_sc_ := [f64(-1), copysign(0, -1), 0, 1, nan()] |
989 | for i := 0; i < vftanh_sc_.len; i++ { |
990 | f := tanh(vftanh_sc_[i]) |
991 | assert alike(tanh_sc_[i], f) |
992 | } |
993 | } |
994 | |
995 | fn test_trunc() { |
996 | // for i := 0; i < vf_.len; i++ { |
997 | // f := trunc(vf_[i]) |
998 | // assert alike(trunc_[i], f) |
999 | // } |
1000 | vfceil_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
1001 | ceil_sc_ := [inf(-1), copysign(0, -1), 0, inf(1), nan()] |
1002 | for i := 0; i < vfceil_sc_.len; i++ { |
1003 | f := trunc(vfceil_sc_[i]) |
1004 | assert alike(ceil_sc_[i], f) |
1005 | } |
1006 | } |
1007 | |
1008 | fn test_gcd() { |
1009 | assert gcd(6, 9) == 3 |
1010 | assert gcd(6, -9) == 3 |
1011 | assert gcd(-6, -9) == 3 |
1012 | assert gcd(0, 0) == 0 |
1013 | } |
1014 | |
1015 | fn test_egcd() { |
1016 | helper := fn (a i64, b i64, expected_g i64) { |
1017 | g, x, y := egcd(a, b) |
1018 | assert g == expected_g |
1019 | assert abs(a * x + b * y) == g |
1020 | } |
1021 | |
1022 | helper(6, 9, 3) |
1023 | helper(6, -9, 3) |
1024 | helper(-6, -9, 3) |
1025 | helper(0, 0, 0) |
1026 | } |
1027 | |
1028 | fn test_lcm() { |
1029 | assert lcm(2, 3) == 6 |
1030 | assert lcm(-2, 3) == 6 |
1031 | assert lcm(-2, -3) == 6 |
1032 | assert lcm(0, 0) == 0 |
1033 | } |
1034 | |
1035 | fn test_digits() { |
1036 | // a small sanity check with a known number like 100, |
1037 | // just written in different base systems: |
1038 | assert digits(100, reverse: true) == [1, 0, 0] |
1039 | assert digits(100, base: 2, reverse: true) == [1, 1, 0, 0, 1, 0, 0] |
1040 | assert digits(100, base: 3, reverse: true) == [1, 0, 2, 0, 1] |
1041 | assert digits(100, base: 4, reverse: true) == [1, 2, 1, 0] |
1042 | assert digits(100, base: 8, reverse: true) == [1, 4, 4] |
1043 | assert digits(100, base: 10, reverse: true) == [1, 0, 0] |
1044 | assert digits(100, base: 12, reverse: true) == [8, 4] |
1045 | assert digits(100, base: 16, reverse: true) == [6, 4] |
1046 | assert digits(100, base: 20, reverse: true) == [5, 0] |
1047 | assert digits(100, base: 32, reverse: true) == [3, 4] |
1048 | assert digits(100, base: 64, reverse: true) == [1, 36] |
1049 | assert digits(100, base: 128, reverse: true) == [100] |
1050 | assert digits(100, base: 256, reverse: true) == [100] |
1051 | |
1052 | assert digits(1234432112344321) == digits(1234432112344321, reverse: true) |
1053 | assert digits(1234432112344321) == [1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 4, 3, 2, 1] |
1054 | |
1055 | assert digits(125, base: 10, reverse: true) == [1, 2, 5] |
1056 | assert digits(125, base: 10).reverse() == [1, 2, 5] |
1057 | |
1058 | assert digits(15, base: 16, reverse: true) == [15] |
1059 | assert digits(127, base: 16, reverse: true) == [7, 15] |
1060 | assert digits(65535, base: 16, reverse: true) == [15, 15, 15, 15] |
1061 | assert digits(-65535, base: 16, reverse: true) == [-15, 15, 15, 15] |
1062 | |
1063 | assert digits(-127) == [7, 2, -1] |
1064 | assert digits(-127).reverse() == [-1, 2, 7] |
1065 | assert digits(-127, reverse: true) == [-1, 2, 7] |
1066 | |
1067 | assert digits(234, base: 7).reverse() == [4, 5, 3] |
1068 | |
1069 | assert digits(67432, base: 12).reverse() == [3, 3, 0, 3, 4] |
1070 | } |
1071 | |
1072 | // Check that math functions of high angle values |
1073 | // return accurate results. [since (vf_[i] + large) - large != vf_[i], |
1074 | // testing for Trig(vf_[i] + large) == Trig(vf_[i]), where large is |
1075 | // a multiple of 2 * pi, is misleading.] |
1076 | fn test_large_cos() { |
1077 | large := 100000.0 * pi |
1078 | for i := 0; i < math.vf_.len; i++ { |
1079 | f1 := math.cos_large_[i] |
1080 | f2 := cos(math.vf_[i] + large) |
1081 | assert soclose(f1, f2, 4e-8) |
1082 | } |
1083 | } |
1084 | |
1085 | fn test_large_sin() { |
1086 | large := 100000.0 * pi |
1087 | for i := 0; i < math.vf_.len; i++ { |
1088 | f1 := math.sin_large_[i] |
1089 | f2 := sin(math.vf_[i] + large) |
1090 | assert soclose(f1, f2, 4e-9) |
1091 | } |
1092 | } |
1093 | |
1094 | fn test_large_tan() { |
1095 | large := 100000.0 * pi |
1096 | for i := 0; i < math.vf_.len; i++ { |
1097 | f1 := math.tan_large_[i] |
1098 | f2 := tan(math.vf_[i] + large) |
1099 | assert soclose(f1, f2, 4e-8) |
1100 | } |
1101 | } |
1102 | |
1103 | fn test_sqrti() { |
1104 | assert sqrti(i64(123456789) * i64(123456789)) == 123456789 |
1105 | assert sqrti(144) == 12 |
1106 | assert sqrti(0) == 0 |
1107 | } |
1108 | |
1109 | fn test_powi() { |
1110 | assert powi(2, 62) == i64(4611686018427387904) |
1111 | assert powi(0, -2) == -1 // div by 0 |
1112 | assert powi(2, -1) == 0 |
1113 | } |
1114 | |
1115 | fn test_count_digits() { |
1116 | assert count_digits(-999) == 3 |
1117 | assert count_digits(-100) == 3 |
1118 | assert count_digits(-99) == 2 |
1119 | assert count_digits(-10) == 2 |
1120 | assert count_digits(-1) == 1 |
1121 | assert count_digits(0) == 1 |
1122 | assert count_digits(1) == 1 |
1123 | assert count_digits(10) == 2 |
1124 | assert count_digits(99) == 2 |
1125 | assert count_digits(100) == 3 |
1126 | assert count_digits(999) == 3 |
1127 | // |
1128 | assert count_digits(12345) == 5 |
1129 | assert count_digits(123456789012345) == 15 |
1130 | assert count_digits(-67345) == 5 |
1131 | } |
1132 | |
1133 | fn test_min_max_int_str() { |
1134 | assert min_i64.str() == '-9223372036854775808' |
1135 | assert max_i64.str() == '9223372036854775807' |
1136 | assert min_i32.str() == '-2147483648' |
1137 | assert max_i32.str() == '2147483647' |
1138 | assert min_i16.str() == '-32768' |
1139 | assert max_i16.str() == '32767' |
1140 | assert min_i8.str() == '-128' |
1141 | assert max_i8.str() == '127' |
1142 | } |
1143 | |
1144 | fn test_maxof_minof() { |
1145 | assert maxof[i8]() == 127 |
1146 | assert maxof[i16]() == 32767 |
1147 | assert maxof[int]() == 2147483647 |
1148 | assert maxof[i32]() == 2147483647 |
1149 | assert maxof[i64]() == 9223372036854775807 |
1150 | assert maxof[u8]() == 255 |
1151 | assert maxof[byte]() == 255 |
1152 | assert maxof[u16]() == 65535 |
1153 | assert maxof[u32]() == 4294967295 |
1154 | assert maxof[u64]() == 18446744073709551615 |
1155 | assert maxof[f32]() == 3.40282346638528859811704183484516925440e+38 |
1156 | assert maxof[f64]() == 1.797693134862315708145274237317043567981e+308 |
1157 | |
1158 | assert minof[i8]() == -128 |
1159 | assert minof[i16]() == -32768 |
1160 | assert minof[int]() == -2147483648 |
1161 | assert minof[i32]() == -2147483648 |
1162 | assert minof[i64]() == -9223372036854775807 - 1 |
1163 | assert minof[u8]() == 0 |
1164 | assert minof[byte]() == 0 |
1165 | assert minof[u16]() == 0 |
1166 | assert minof[u32]() == 0 |
1167 | assert minof[u64]() == 0 |
1168 | assert minof[f32]() == -3.40282346638528859811704183484516925440e+38 |
1169 | assert minof[f64]() == -1.797693134862315708145274237317043567981e+308 |
1170 | } |