mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-15 04:32:21 +00:00
275 lines
16 KiB
Text
275 lines
16 KiB
Text
#include "../../../smartcont/mathlib.fc";
|
|
|
|
forall X -> (tuple, ()) ~tset(tuple t, int idx, X val) asm(t val idx) "SETINDEXVAR";
|
|
|
|
;; computes 1-acos(x)/Pi by a very simple, extremely slow (~70k gas) and imprecise method
|
|
;; fixed256 acos_prepare_slow(fixed255 x);
|
|
int acos_prepare_slow_f255(int x) inline {
|
|
x -= (x == 0);
|
|
int t = 1;
|
|
repeat (255) {
|
|
t = t * sgn(x) * 2 + 1; ;; decode Gray code (sgn(x_0), sgn(x_1), ...)
|
|
x = (-1 << 255) - muldivr(x, - x, 1 << 254); ;; iterate x := 2*x^2 - 1 = cos(2*acos(x))
|
|
}
|
|
return abs(t);
|
|
}
|
|
|
|
;; extremely slow (~70k gas) and somewhat imprecise (very imprecise when x is small), for testing only
|
|
;; fixed254 acos_slow(fixed255 x);
|
|
int acos_slow_f255(int x) inline_ref {
|
|
int t = acos_prepare_slow_f255(x);
|
|
return - mulrshiftr256(t + (-1 << 256), Pi_const_f254());
|
|
}
|
|
|
|
;; fixed255 asin_slow(fixed255 x);
|
|
int asin_slow_f255(int x) inline_ref {
|
|
int t = acos_prepare_slow_f255(abs(x)) % (1 << 255);
|
|
return muldivr(t, Pi_const_f254(), 1 << 255) * sgn(x);
|
|
}
|
|
|
|
tuple test_nrand(int n) inline_ref {
|
|
tuple t = empty_tuple();
|
|
repeat (255) {
|
|
t~tpush(0);
|
|
}
|
|
repeat (n) {
|
|
int x = fixed248::nrand();
|
|
int bucket = (abs(x) >> 243); ;; 255 buckets starting from x=0, each 1/32 wide
|
|
t~tset(bucket, t.at(bucket) + 1);
|
|
}
|
|
return t;
|
|
}
|
|
|
|
int geom_mean_test(int x, int y) method_id(10000) {
|
|
return geom_mean(x, y);
|
|
}
|
|
int tan_f260_test(int x) method_id(10001) {
|
|
return tan_f260(x);
|
|
}
|
|
(int, int) sincosm1_f259_test(int x) method_id(10002) {
|
|
return sincosm1_f259(x);
|
|
}
|
|
(int, int) sincosn_f256_test(int x, int y) method_id(10003) {
|
|
return sincosn_f256(x, y);
|
|
}
|
|
(int, int) sincosm1_f256_test(int x) method_id(10004) {
|
|
return sincosm1_f256(x);
|
|
}
|
|
(int, int) tan_aux_f256_test(x) method_id(10005) {
|
|
return tan_aux_f256(x);
|
|
}
|
|
(int) fixed248::tan_test(x) method_id(10006) {
|
|
return fixed248::tan(x);
|
|
}
|
|
{-
|
|
(int) atanh_alt_f258_test(x) method_id(10007) {
|
|
return atanh_alt_f258(x);
|
|
}
|
|
-}
|
|
(int) atanh_f258_test(x, y) method_id(10008) {
|
|
return atanh_f258(x, y);
|
|
}
|
|
(int) atanh_f261_test(x, y) method_id(10009) {
|
|
return atanh_f261(x, y);
|
|
}
|
|
|
|
(int, int) log2_aux_f256_test(x) method_id(10010) {
|
|
return log2_aux_f256(x);
|
|
}
|
|
(int, int) log_aux_f256_test(x) method_id(10011) {
|
|
return log_aux_f256(x);
|
|
}
|
|
int fixed248::pow_test(x, y) method_id(10012) {
|
|
return fixed248::pow(x, y);
|
|
}
|
|
int exp_log_div(x, y) method_id(10013) {
|
|
return fixed248::exp(fixed248::log(x << 248) ~/ y);
|
|
}
|
|
int fixed248::log_test(x) method_id(10014) {
|
|
return fixed248::log(x);
|
|
}
|
|
(int,int) log_aux_f257_test(x) method_id(10015) {
|
|
return log_aux_f257(x);
|
|
}
|
|
(int,int) fixed248::sincos_test(x) method_id(10016) {
|
|
return fixed248::sincos(x);
|
|
}
|
|
int fixed248::exp_test(x) method_id(10017) {
|
|
return fixed248::exp(x);
|
|
}
|
|
int fixed248::exp2_test(x) method_id(10018) {
|
|
return fixed248::exp2(x);
|
|
}
|
|
int expm1_f257_test(x) method_id(10019) {
|
|
return expm1_f257(x);
|
|
}
|
|
int atan_f255_test(x) method_id(10020) {
|
|
return atan_f255(x);
|
|
}
|
|
int atan_f259_test(x, n) method_id(10021) {
|
|
return atan_f259(x, n);
|
|
}
|
|
(int, int) atan_aux_f256_test(x) method_id(10022) {
|
|
return atan_aux_f256(x);
|
|
}
|
|
int asin_f255_test(x) method_id(10023) {
|
|
return asin_f255(x);
|
|
}
|
|
int asin_slow_f255_test(x) method_id(10024) {
|
|
return asin_slow_f255(x);
|
|
}
|
|
int acos_f255_test(x) method_id(10025) {
|
|
return acos_f255(x);
|
|
}
|
|
int acos_slow_f255_test(x) method_id(10026) {
|
|
return acos_slow_f255(x);
|
|
}
|
|
int fixed248::atan_test(x) method_id(10027) {
|
|
return fixed248::atan(x);
|
|
}
|
|
int fixed248::acot_test(x) method_id(10028) {
|
|
return fixed248::acot(x);
|
|
}
|
|
|
|
_ main() {
|
|
int One = 1;
|
|
;; repeat(76 / 4) { One *= 10000; }
|
|
int sqrt2 = geom_mean(One, 2 * One);
|
|
int sqrt3 = geom_mean(One, 3 * One);
|
|
;; return geom_mean(-1 - (-1 << 256), -1 - (-1 << 256));
|
|
;; return geom_mean(-1 - (-1 << 256), -2 - (-1 << 256));
|
|
;; return geom_mean(-1 - (-1 << 256), 1 << 255);
|
|
;; return (sqrt2, geom_mean(sqrt2, One)); ;; (sqrt(2), 2^(1/4))
|
|
;; return (sqrt3, geom_mean(sqrt3, One)); ;; (sqrt(3), 3^(1/4))
|
|
;; return geom_mean(3 << 254, 1 << 254);
|
|
;; return geom_mean(3, 5);
|
|
;; return tan_f260(115641670674223639132965820642403718536242645001775371762318060545014644837101 - 1);
|
|
;; return tan_f260(15 << 252); ;; tan(15/256) * 2^260
|
|
;; return sincosm1_f259(1 << 255); ;; (sin,1-cos)(1/16) * 2^259
|
|
;; return sincosm1_f259(115641670674223639132965820642403718536242645001775371762318060545014644837101 - 1);
|
|
;; return sincosm1_f256((1 << 255) - 1 + (1 << 255)); ;; (sin,1-cos)(1-2^(-256))
|
|
;; return sincosm1_f256(Pi_const_f254()); ;; (sin,1-cos)(Pi/4)
|
|
;; return sincosn_f256(Pi_const_f254(), 0); ;; (sin,-cos)(Pi/4)
|
|
;; return sincosn_f256((1 << 255) + 1, 0); ;; (sin,-cos)(1/2+1/2^256)
|
|
;; return sincosn_f256(1 << 254, 0);
|
|
;; return sincosn_f256(touch(15) << 252, 0); ;; (sin,-cos)(15/16)
|
|
;; return sincosm1_f256(touch(15) << 252); ;; (sin,1-cos)(15/16)
|
|
;; return sincosn_f256(60628596148627720713372490462954977108898896221398738326462025186323149077698, 0); ;; (sin,-cos)(Pi/6)
|
|
;; return sincosm1_f256(60628596148627720713372490462954977108898896221398738326462025186323149077698); ;; (sin,1-cos)(Pi/6)
|
|
;; return tan_aux_f256(1899 << 245); ;; (p,q) such that p/q=tan(1899/2048)
|
|
;; return fixed248::tan(11 << 248); ;; tan(11)
|
|
;; return atanh_alt_f258(1 << 252); ;; atanh(1/64) * 2^258
|
|
;; return atanh_f258(1 << 252, 18); ;; atanh(1/64) * 2^258
|
|
;; return atanh_f261(muldivr(64, 1 << 255, 55), 18); ;; atanh(1/55) * 2^261
|
|
;; return log2_aux_f256(1 << 255);
|
|
;; return log2_aux_f256(-1 - (-1 << 256)); ;; log2(2-1/2^255))*2^256 ~ 2^256 - 1.43
|
|
;; return log_aux_f256(-1 - (-1 << 256));
|
|
;; return log_aux_f256(3); ;; log(3/2)*2^256
|
|
;; return fixed248::pow(3 << 248, 3 << 248); ;; 3^3
|
|
;; return fixed248::exp(fixed248::log(5 << 248) ~/ 7); ;; exp(log(5)/7) = 5^(1/7)
|
|
;; return fixed248::log(Pi_const_f254() ~>> 6); ;; log(Pi)
|
|
;; return atanh_alt_f258(1 << 255); ;; atanh(1/8) * 2^258
|
|
;; return atanh_f258(1 << 255, 37); ;; atanh(1/8) * 2^258
|
|
;; return atanh_f258(81877371507464127617551201542979628307507432471243237061821853600756754782485, 36); ;; atanh(sqrt(2)/8) * 2^258
|
|
;; return log_aux_f257(Pi_const_f254()); ;; log(Pi/4)
|
|
;; return log_aux_f257(3 << 254); ;; log(3)
|
|
;; return atanh_alt_f258(81877371507464127617551201542979628307507432471243237061821853600756754782485); ;; atanh(sqrt(2)/8) * 2^258
|
|
;; return fixed248::sincos(Pi_const_f254() ~/ (64 * 3)); ;; (sin,cos)(Pi/3)
|
|
;; return fixed248::exp(3 << 248); ;; exp(3)*2^248
|
|
;; return fixed248::exp2((1 << 248) ~/ 5); ;; 2^(1/5)*2^248
|
|
;; return fixed248::pow(3 << 248, -3 << 247); ;; 3^(-1.5)
|
|
;; return fixed248::pow(10 << 248, -70 << 248); ;; 10^(-70)
|
|
;; return fixed248::pow(fixed248::Pi_const(), touch(3) << 248); ;; Pi^3 ~ 31.006, computed more precisely
|
|
;; return fixed248::pow(fixed248::Pi_const(), fixed248::Pi_const()); ;; Pi^Pi, more precisely
|
|
;; return fixed248::exp(fixed248::log(fixed248::Pi_const()) * 3); ;; Pi^3 ~ 31.006
|
|
;; return fixed248::exp(muldivr(fixed248::log(fixed248::Pi_const()), fixed248::Pi_const(), 1 << 248)); ;; Pi^Pi
|
|
;; return fixed248::sin(fixed248::log(fixed248::exp(fixed248::Pi_const()))); ;; sin(log(e^Pi))
|
|
;; return expm1_f257(1 << 255); ;; (exp(1/4)-1)*2^256
|
|
;; return expm1_f257(-1 << 256); ;; (exp(-1/2)-1)*2^256 (argument out of range, will overflow)
|
|
;; return expm1_f257(log2_const_f256()); ;; (exp(log(2)/2)-1)*2^256
|
|
;; return expm1_f257(- log2_const_f256()); ;; (exp(-log(2)/2)-1)*2^256
|
|
;; return tanh_f258(log2_const_f256(), 17); ;; tanh(log(2)/4)*2^258
|
|
;; return atan_f255(0xa0 << 247);
|
|
;; return atan_f259(1 << 255, 26); ;; atan(1/16)
|
|
;; return atan_f259(touch(2273) << 244, 26); ;; atan(2273/2^15)
|
|
;; return atan_aux_f256(0xa0 << 248);
|
|
;; return atan_aux_f256(-1 - (-1 << 256));
|
|
;; return atan_aux_f256(-1 << 256);
|
|
;; return atan_aux_f256(1); ;; atan(1/2^256)*2^261 = 32
|
|
;;return fixed248::nrand();
|
|
;; return test_nrand(100000);
|
|
int One = touch(1 << 255);
|
|
;; return asin_f255(One);
|
|
;; return asin_f255(-2 * One ~/ -3);
|
|
int arg = muldivr(12, One, 17); ;; 12/17
|
|
;; return [ asin_slow_f255(arg), asin_f255(arg) ];
|
|
;; return [ acos_slow_f255(arg), acos_f255(arg) ];
|
|
;; return 4 * atan_f255(One ~/ 5) - atan_f255(One ~/ 239); ;; 4 * atan(1/5) - atan(1/239) = Pi/4 as fixed255
|
|
int One = touch(1 << 248);
|
|
;; return fixed248::atan(One) ~/ 5); ;; atan(1/5)
|
|
;; return fixed248::acot(One ~/ 239); ;; atan(1/5)
|
|
}
|
|
|
|
{-
|
|
method_id | in | out
|
|
TESTCASE | 10000 | -1-(-1<<256) -1-(-1<<256) | 115792089237316195423570985008687907853269984665640564039457584007913129639935
|
|
TESTCASE | 10000 | -1-(-1<<256) -2-(-1<<256) | 115792089237316195423570985008687907853269984665640564039457584007913129639934
|
|
TESTCASE | 10000 | -1-(-1<<256) 1<<255 | 81877371507464127617551201542979628307507432471243237061821853600756754782485
|
|
TESTCASE | 10000 | 1 2 | 1
|
|
TESTCASE | 10000 | 1 3 | 2
|
|
TESTCASE | 10000 | 3<<254, 1<<254 | 50139445418395255283694704271811692336355250894665672355503583528635147053497
|
|
TESTCASE | 10000 | 3 5 | 4
|
|
TESTCASE | 10001 | 115641670674223639132965820642403718536242645001775371762318060545014644837101-1 | 115792089237316195423570985008687907853269984665640564039457584007913129639935
|
|
TESTCASE | 10001 | 15<<252 | 108679485937549714997960660780289583146059954551846264494610741505469565211201
|
|
|
|
TESTCASE | 10002 | 1<<255 | 57858359242454268843682786479537198006144860419130642837770554273561536355094 28938600351875109040123440645416448095273333920390487381363947585666516031269
|
|
TESTCASE | 10002 | 90942894222941581070058735694432465663348344332098107489693037779484723616546 | 90796875678616203090520439851979829600860326752181983760731669850687818036503 71369031536005973567205947792557760023823761636922618688720973932041901854510
|
|
TESTCASE | 10002 | 115641670674223639132965820642403718536242645001775371762318060545014644837100 | 115341536360906404779899502576747487978354537254490211650198994186870666100480 115341536360906404779899502576747487978354537254490211650198994186870666100479
|
|
TESTCASE | 10003 | 90942894222941581070058735694432465663348344332098107489693037779484723616546 0 | 81877371507464127617551201542979628307507432471243237061821853600756754782485 -81877371507464127617551201542979628307507432471243237061821853600756754782486
|
|
TESTCASE | 10003 | (1<<255)+1 0 | 55513684748706254392157395574451324146997108788015526773113170656738693667657 -101617118319522600545601981648807607350213579319835970884288805016705398675944
|
|
TESTCASE | 10003 | 1<<254 0 | 28647421327665059059430596260119789787021370826354543144805343654507971817712 -112192393597863122712065585177748900737784171216163716639418346853706594800924
|
|
TESTCASE | 10003 | 15<<252 0 | 93337815620236900315136494926097782162348358704087992554326802765553037216157 -68526346066204767396483080633934170508153877799043171682610011603005473885083
|
|
TESTCASE | 10004 | 15<<252 | 93337815620236900315136494926097782162348358704087992554326802765553037216158 94531486342222856054175808749507474690232213733194784713695144809815311509707
|
|
TESTCASE | 10003 | 60628596148627720713372490462954977108898896221398738326462025186323149077698 0 | 57896044618658097711785492504343953926634992332820282019728792003956564819968 -100278890836790510567389408543623384672710501789331344711007167057270294106993
|
|
TESTCASE | 10004 | 60628596148627720713372490462954977108898896221398738326462025186323149077698 | 57896044618658097711785492504343953926634992332820282019728792003956564819968 31026396801051369712363152930129046361118965752618438656900833901285671065886
|
|
TESTCASE | 10005 | 1899<<245 | -115784979074977116522606932816046735344768048129666123117516779696532375620701 -86847621900007587791673148476644866514014227467564880140262768165345715058771
|
|
TESTCASE | 10006 | 11<<248 | -102200470999497240398685962406597118965525125432278008915850368651878945159221
|
|
TESTCASE | 10008 | 1<<252 18 | 7237594612640731814076778712183932891481921212865048737772958953246047977071
|
|
TESTCASE! | 10009 | 64*(1<<255)//55 18 | 67377367986958444187782963285047188951340314639925508148698906136973510008513
|
|
TESTCASE | 10010 | 1<<255 | 0 255
|
|
TESTCASE | 10011 | -1-(-1<<256) | 80260960185991308862233904206310070533990667611589946606122867505419956976171 255
|
|
TESTCASE | 10012 | 3<<248 3<<248 | 12212446911748192486079752325135052781399568695204278238536542063334587891712
|
|
TESTCASE | 10013 | 5 7 | 569235245303856216139605450142923208167703167128528666640203654338408315932
|
|
TESTCASE | 10014 | 1420982722233462204219667745225507275989817880189032929526453715304448806508 | 517776035526939558040896860590142614178014859368681705591403663865964112176
|
|
TESTCASE | 10008 | 1<<255 37 | 58200445412255555045265806996802932280233368707362818578692888102488340124094
|
|
TESTCASE | 10008 | 81877371507464127617551201542979628307507432471243237061821853600756754782485 36 | 82746618329032515754939514227666784789465120373484337368014239356561508382845
|
|
TESTCASE | 10015 | 90942894222941581070058735694432465663348344332098107489693037779484723616546 | -55942510554172181731996424203087263676819062449594753161692794122306202470292 256
|
|
TESTCASE | 10015 | 3<<254 | -66622616410625360568738677407433830899150908037353507097280251369610028875158 256
|
|
TESTCASE | 10016 | 90942894222941581070058735694432465663348344332098107489693037779484723616546//(64*3) | 391714417331212931903864877123528846377775397614575565277371746317462086355 226156424291633194186662080095093570025917938800079226639565593765455331328
|
|
TESTCASE | 10017 | 3<<248 | 9084946421051389814103830025729847734065792062362132089390904679466687950835
|
|
TESTCASE | 10018 | (1<<248)//5 | 519571025111621076330285524602776985448579272766894385941850747946908706857
|
|
TESTCASE | 10012 | 3<<248 -3<<247 | 87047648295825095978636639360784188083950088358794570061638165848324908079
|
|
TESTCASE | 10012 | 10<<248 -70<<248 | 45231
|
|
TESTCASE | 10012 | 1420982722233462204219667745225507275989817880189032929526453715304448806508 3<<248 | 14024537329227316173680050897643053638073167245065581681188087336877135047241
|
|
TESTCASE | 10012 | 1420982722233462204219667745225507275989817880189032929526453715304448806508 1420982722233462204219667745225507275989817880189032929526453715304448806508 | 16492303277433924047657446877966346821161732581471802839855102123372676002295
|
|
TESTCASE | 10019 | 1<<255 | 65775792789545756849501669218806308540691279864498696756901136302101823231959
|
|
TESTCASE | 10019 | -1<<255 | -51226238931640701466578648374135745377468902266335737558089915608594425303282
|
|
|
|
TESTCASE | 10020 | 160<<247 | 32340690885082755723307749066376646841771751777398167772823878380310576779097
|
|
TESTCASE | 10021 | 1<<255 26 | 57820835337111819566482910321201859268121322500887685881159030272507322418551
|
|
TESTCASE | 10021 | 2273<<244 26 | 64153929153128256059565403901040178355488584937372975321150754259394300105908
|
|
TESTCASE | 10022 | 160<<248 | 18 -13775317617017974742132028403521581424991093186766868001115299479309514610238
|
|
TESTCASE | 10022 | -1-(-1<<256) | 25 16312150880916231694896252427912541090503675654570543195394548083530005073282
|
|
TESTCASE | 10022 | -1<<256 | -25 -16312150880916231694896252427912541090503675654570543195394548083530005073298
|
|
TESTCASE | 10022 | 1 | 0 32
|
|
|
|
TESTCASE | 10023 | 1<<255 | 90942894222941581070058735694432465663348344332098107489693037779484723616546
|
|
TESTCASE | 10023 | (1-(1<<255))//-3 | 19675212872822715586637341573564384553677006914302429002469838095945333339604
|
|
TESTCASE | 10023 | 12*(1<<255)//17 | 45371280744427205854111943101074857545572584208710061167826656461897302968384
|
|
TESTCASE | 10024 | 12*(1<<255)//17 | 45371280744427205854111943101074857545572584208710061167826656461897302968387
|
|
TESTCASE | 10025 | 12*(1<<255)//17 | 22785806739257187607973396296678804058887880061694023160933190658793710324081
|
|
TESTCASE | 10026 | 12*(1<<255)//17 | 22785806739257187607973396296678804058887880061694023160933190658793710324080
|
|
|
|
TESTCASE | 10027 | (1<<248)//5 | 89284547973388213553327350968415123522888028497458323165947767504203347189
|
|
TESTCASE | 10028 | (1<<248)//239 | 708598849781543798951441405045469962900811296151941404481049216461523216127
|
|
-}
|