mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Add PRNG with normal distribution to mathlib.fc (#646)
* Add random with normal distribution * Fix hex arguments in mathlib testcases
This commit is contained in:
		
							parent
							
								
									4d5ded5761
								
							
						
					
					
						commit
						7da30e1e7f
					
				
					 4 changed files with 385 additions and 131 deletions
				
			
		| 
						 | 
				
			
			@ -66,6 +66,21 @@ for ti, tf in enumerate(tests):
 | 
			
		|||
        print("Error: no test cases", file=sys.stderr)
 | 
			
		||||
        exit(2)
 | 
			
		||||
 | 
			
		||||
    # preprocess arithmetics in input
 | 
			
		||||
    for i in range(len(cases)):
 | 
			
		||||
      inputs = cases[i][1].split(" ")
 | 
			
		||||
      processed_inputs = ""
 | 
			
		||||
      for in_arg in inputs:
 | 
			
		||||
        if "x{" in in_arg:
 | 
			
		||||
          processed_inputs += in_arg
 | 
			
		||||
          continue
 | 
			
		||||
        # filter and execute
 | 
			
		||||
        # is it safe enough?
 | 
			
		||||
        filtered_in = "".join(filter(lambda x: x in "0x123456789()+-*/<>", in_arg))
 | 
			
		||||
        if(filtered_in):
 | 
			
		||||
          processed_inputs += str(eval(filtered_in)) + " ";
 | 
			
		||||
      cases[i][1] = processed_inputs.strip()
 | 
			
		||||
 | 
			
		||||
    with open(RUNNER_FIF, "w") as f:
 | 
			
		||||
        print("\"%s\" include <s constant code" % COMPILED_FIF, file=f)
 | 
			
		||||
        for function, test_in, _ in cases:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										275
									
								
								crypto/func/auto-tests/tests/test-math.fc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								crypto/func/auto-tests/tests/test-math.fc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,275 @@
 | 
			
		|||
#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
 | 
			
		||||
-}
 | 
			
		||||
| 
						 | 
				
			
			@ -4,6 +4,9 @@
 | 
			
		|||
 -
 | 
			
		||||
 -}
 | 
			
		||||
 | 
			
		||||
#include "stdlib.fc";
 | 
			
		||||
#pragma version >=0.4.2;
 | 
			
		||||
 | 
			
		||||
{---------------- HIGH-LEVEL FUNCTION DECLARATIONS -----------------}
 | 
			
		||||
{-
 | 
			
		||||
 Most functions declared here work either with integers or with fixed-point numbers of type `fixed248`.
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +66,17 @@ int fixed248::atan(int x) inline_ref;
 | 
			
		|||
;; fixed248 acot(fixed248 x);
 | 
			
		||||
int fixed248::acot(int x) inline_ref;
 | 
			
		||||
 | 
			
		||||
;; random number uniformly distributed in [0..1)
 | 
			
		||||
;; fixed248 random();
 | 
			
		||||
int fixed248::random() impure inline;
 | 
			
		||||
;; random number with standard normal distribution (2100 gas on average)
 | 
			
		||||
;; fixed248 nrand();
 | 
			
		||||
int fixed248::nrand() impure inline;
 | 
			
		||||
;; generates a random number approximately distributed according to the standard normal distribution (1200 gas)
 | 
			
		||||
;; (fails chi-squared test, but it is shorter and faster than fixed248::nrand())
 | 
			
		||||
;; fixed248 nrand_fast();
 | 
			
		||||
int fixed248::nrand_fast() impure inline;
 | 
			
		||||
 | 
			
		||||
-}  ;; end (declarations)
 | 
			
		||||
 | 
			
		||||
{-------------------- INTERMEDIATE FUNCTIONS -----------------------}
 | 
			
		||||
| 
						 | 
				
			
			@ -125,30 +139,27 @@ int asin_f255(int x);
 | 
			
		|||
;; fixed254 acos(fixed255 x);
 | 
			
		||||
int acos_f255(int x);
 | 
			
		||||
 | 
			
		||||
;; generates normally distributed pseudo-random number
 | 
			
		||||
;; fixed252 nrand();
 | 
			
		||||
int nrand_f252(int x);
 | 
			
		||||
 | 
			
		||||
;; a faster and shorter variant of nrand_f252() that fails chi-squared test
 | 
			
		||||
;; (should suffice for most purposes)
 | 
			
		||||
;; fixed252 nrand_fast();
 | 
			
		||||
int nrand_fast_f252(int x);
 | 
			
		||||
 | 
			
		||||
-}  ;; end (declarations)
 | 
			
		||||
 | 
			
		||||
{---------------- MISSING OPERATIONS AND BUILT-INS -----------------}
 | 
			
		||||
 | 
			
		||||
int sgn(int x) asm "SGN";
 | 
			
		||||
int abs(int x) asm "ABS";
 | 
			
		||||
int min(int x, int y) asm "MIN";
 | 
			
		||||
 | 
			
		||||
;; compute floor(log2(x))+1
 | 
			
		||||
int log2_floor_p1(int x) asm "UBITSIZE";
 | 
			
		||||
 | 
			
		||||
;; FunC compiler emits MULDIVC instruction, but Asm.fif usually does not know it
 | 
			
		||||
;; add the following line to your Asm.fif if necessary
 | 
			
		||||
;; x{A986} @Defop MULDIVC
 | 
			
		||||
 | 
			
		||||
;; the following instructions might have been emitted by muldivmod() and muldivmodr() builtins, but FunC does not have these
 | 
			
		||||
;; x{A9A5} @Defop MULRSHIFTR
 | 
			
		||||
int mulrshiftr(int x, int y, int s) asm "MULRSHIFTR";
 | 
			
		||||
;; x{A9B5} @Defop(8u+1) MULRSHIFTR#
 | 
			
		||||
int mulrshiftr256(int x, int y) asm "256 MULRSHIFTR#";
 | 
			
		||||
;; x{A9BC} @Defop(8u+1) MULRSHIFT#MOD
 | 
			
		||||
(int, int) mulrshift256mod(int x, int y) asm "256 MULRSHIFT#MOD";
 | 
			
		||||
;; x{A9BD} @Defop(8u+1) MULRSHIFTR#MOD
 | 
			
		||||
(int, int) mulrshiftr256mod(int x, int y) asm "256 MULRSHIFTR#MOD";
 | 
			
		||||
(int, int) mulrshiftr255mod(int x, int y) asm "255 MULRSHIFTR#MOD";
 | 
			
		||||
(int, int) mulrshiftr248mod(int x, int y) asm "248 MULRSHIFTR#MOD";
 | 
			
		||||
| 
						 | 
				
			
			@ -156,39 +167,34 @@ int mulrshiftr256(int x, int y) asm "256 MULRSHIFTR#";
 | 
			
		|||
(int, int) mulrshiftr6mod(int x, int y) asm "6 MULRSHIFTR#MOD";
 | 
			
		||||
(int, int) mulrshiftr7mod(int x, int y) asm "7 MULRSHIFTR#MOD";
 | 
			
		||||
 | 
			
		||||
;; these instructions might have been emitted by muldivmodr(..., 1 << N, ...) built-ins
 | 
			
		||||
;; x{A9D5} @Defop(8u+1) LSHIFT#DIVR
 | 
			
		||||
int lshift256divr(int x, int y) asm "256 LSHIFT#DIVR";
 | 
			
		||||
;; x{A9DD} @Defop(8u+1) LSHIFT#DIVMODR
 | 
			
		||||
(int, int) lshift256divmodr(int x, int y) asm "256 LSHIFT#DIVMODR";
 | 
			
		||||
(int, int) lshift255divmodr(int x, int y) asm "255 LSHIFT#DIVMODR";
 | 
			
		||||
(int, int) lshift2divmodr(int x, int y) asm "2 LSHIFT#DIVMODR";
 | 
			
		||||
(int, int) lshift7divmodr(int x, int y) asm "7 LSHIFT#DIVMODR";
 | 
			
		||||
;; x{A9CD} @Defop LSHIFTDIVMODR
 | 
			
		||||
(int, int) lshiftdivmodr(int x, int y, int s) asm "LSHIFTDIVMODR";
 | 
			
		||||
 | 
			
		||||
;; these instructions might have been emitted by divmodr(..., 1 << NN) or divmod(..., 1 << N) built-ins
 | 
			
		||||
;; but FunC does not have divmodr(), and divmod() always compiles to "DIVMOD"
 | 
			
		||||
;; x{A93D} @Defop(8u+1) RSHIFTR#MOD
 | 
			
		||||
(int, int) rshiftr256mod(int x) asm "256 RSHIFTR#MOD";
 | 
			
		||||
(int, int) rshiftr248mod(int x) asm "248 RSHIFTR#MOD";
 | 
			
		||||
(int, int) rshiftr4mod(int x) asm "4 RSHIFTR#MOD";
 | 
			
		||||
;; x{A93C} @Defop(8u+1) RSHIFT#MOD
 | 
			
		||||
(int, int) rshift3mod(int x) asm "3 RSHIFT#MOD";
 | 
			
		||||
 | 
			
		||||
;; computes y - x (FunC compiler does not try to use this by itself) 
 | 
			
		||||
int sub_rev(int x, int y) asm "SUBR";
 | 
			
		||||
 | 
			
		||||
int nan() asm "PUSHNAN";
 | 
			
		||||
int is_nan(int x) asm "ISNAN";
 | 
			
		||||
 | 
			
		||||
{------------------------ SQUARE ROOTS ----------------------------}
 | 
			
		||||
 | 
			
		||||
;; computes sqrt(a*b) exactly rounded to the nearest integer
 | 
			
		||||
;; for all 0 <= a, b <= 2^256-1
 | 
			
		||||
;; may be used with b=1 or b=scale of fixed-point numbers
 | 
			
		||||
int geom_mean(int a, int b) inline_ref {
 | 
			
		||||
  if (min(a, b) <= 0) {
 | 
			
		||||
  ifnot (min(a, b)) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  int s = log2_floor_p1(a);
 | 
			
		||||
  int s = log2_floor_p1(a);   ;; throws out of range error if a < 0 or b < 0
 | 
			
		||||
  int t = log2_floor_p1(b);
 | 
			
		||||
  ;; NB: (a-b)/2+b == (a+b)/2, but without overflow for large a and b
 | 
			
		||||
  int x = (s == t ? (a - b) / 2 + b : 1 << ((s + t) / 2));
 | 
			
		||||
| 
						 | 
				
			
			@ -313,9 +319,6 @@ int expm1_f257(int x) inline_ref {
 | 
			
		|||
  return x - muldivr(x2, t / 2, a + mulrshiftr256(x, t) ~/ 4) ~/ 4;  ;; x - x^2 * (x-a) / (a + x*(x-a))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
;; used to avoid broken optimisations in older versions of FunC
 | 
			
		||||
int minus_one() asm "-1 PUSHINT";
 | 
			
		||||
 | 
			
		||||
;; expm1_f257() may be used to implement specific fixed-point exponentials
 | 
			
		||||
;; example:
 | 
			
		||||
;; fixed248 exp(fixed248 x)
 | 
			
		||||
| 
						 | 
				
			
			@ -327,8 +330,7 @@ int fixed248::exp(int x) inline_ref {
 | 
			
		|||
  x = 2 * x - muldivr(q, l2d, 1 << 127);
 | 
			
		||||
  int y = expm1_f257(x);
 | 
			
		||||
  ;; result is (1 + y) * (2^q) --> ((1 << 257) + y) >> (9 - q)
 | 
			
		||||
  return (y ~>> (9 - q)) - (minus_one() << (248 + q));
 | 
			
		||||
  ;; (-1 << (248 + q)) is compiled into non-existent instruction NEGPOW2
 | 
			
		||||
  return (y ~>> (9 - q)) - (-1 << (248 + q));
 | 
			
		||||
  ;; note that (y ~>> (9 - q)) + (1 << (248 + q)) leads to overflow when q=8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +341,7 @@ int fixed248::exp2(int x) inline_ref {
 | 
			
		|||
  (int q, x) = rshiftr248mod(x);
 | 
			
		||||
  x = muldivr(x, log2_const_f256(), 1 << 247);
 | 
			
		||||
  int y = expm1_f257(x);
 | 
			
		||||
  return (y ~>> (9 - q)) - (minus_one() << (248 + q));
 | 
			
		||||
  return (y ~>> (9 - q)) - (-1 << (248 + q));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{--------------------- TRIGONOMETRIC FUNCTIONS -----------------------}
 | 
			
		||||
| 
						 | 
				
			
			@ -662,7 +664,7 @@ int fixed248::pow(int x, int y) inline_ref {
 | 
			
		|||
    return - (sq == 0);   ;; underflow
 | 
			
		||||
  }
 | 
			
		||||
  int y = expm1_f257(mulrshiftr256(ll, log2_const_f256()));
 | 
			
		||||
  return (y ~>> (9 - q)) - (minus_one() << sq);
 | 
			
		||||
  return (y ~>> (9 - q)) - (-1 << sq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{--------------------- INVERSE TRIGONOMETRIC FUNCTIONS -------------------}
 | 
			
		||||
| 
						 | 
				
			
			@ -795,7 +797,7 @@ int atan_f256_small(int x) inline_ref {
 | 
			
		|||
;; fixed255 asin(fixed255 x);
 | 
			
		||||
int asin_f255(int x) inline_ref {
 | 
			
		||||
  int a = fixed255::One - fixed255::sqr(x);  ;; a:=1-x^2
 | 
			
		||||
  if (a <= 0) {
 | 
			
		||||
  ifnot (a) {
 | 
			
		||||
    return sgn(x) * Pi_const_f254();   ;; Pi/2 or -Pi/2
 | 
			
		||||
  }
 | 
			
		||||
  int y = fixed255::sqrt(a);   ;; sqrt(1-x^2)
 | 
			
		||||
| 
						 | 
				
			
			@ -806,7 +808,7 @@ int asin_f255(int x) inline_ref {
 | 
			
		|||
;; fixed254 acos(fixed255 x);
 | 
			
		||||
int acos_f255(int x) inline_ref {
 | 
			
		||||
  int Pi = Pi_const_f254();
 | 
			
		||||
  if (x <= (-1 << 255)) {
 | 
			
		||||
  if (x == (-1 << 255)) {
 | 
			
		||||
    return Pi;   ;; acos(-1) = Pi
 | 
			
		||||
  }
 | 
			
		||||
  Pi /= 2;
 | 
			
		||||
| 
						 | 
				
			
			@ -858,3 +860,65 @@ int fixed248::acot(int x) inline_ref {
 | 
			
		|||
  ;; now acot(x) = - z - q*atan(1/32) + s*(Pi/2), z is fixed261
 | 
			
		||||
  return (s * Pi_const_f254() - z ~/ 64 - muldivr(q, Atan1_32_f261(), 64)) ~/ 128;   ;; compute in fixed255, then convert 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{--------------------- PSEUDO-RANDOM NUMBERS -------------------}
 | 
			
		||||
 | 
			
		||||
;; random number with standard normal distribution N(0,1)
 | 
			
		||||
;; generated by Kinderman--Monahan ratio method modified by J.Leva
 | 
			
		||||
;; spends ~ 2k..3k gas on average
 | 
			
		||||
;; fixed252 nrand();
 | 
			
		||||
int nrand_f252() impure inline_ref {
 | 
			
		||||
  var (x, s, t, A, B, r0) = (nan(), touch(29483) << 236, touch(-3167) << 239, 12845, 16693, 9043);
 | 
			
		||||
  ;; 4/sqrt(e*Pi) = 1.369 loop iterations on average
 | 
			
		||||
  do {
 | 
			
		||||
    var (u, v) = (random() / 16 + 1, muldivr(random() - (1 << 255), 7027, 1 << 16));   ;; fixed252; 7027=ceil(sqrt(8/e)*2^12)
 | 
			
		||||
    int va = abs(v);
 | 
			
		||||
    var (u1, v1) = (u - s, va - t);   ;; (u - 29483/2^16, abs(v) + 3167/2^13) as fixed252
 | 
			
		||||
    ;; Q := u1^2 + v1 * (A*v1 - B*u1) as fixed252 where A=12845/2^16, B=16693/2^16
 | 
			
		||||
    int Q = muldivr(u1, u1, 1 << 252) + muldivr(v1, muldivr(v1, A, 1 << 16) - muldivr(u1, B, 1 << 16), 1 << 252);
 | 
			
		||||
    ;; must have 9043 / 2^15 < Q < 9125 / 2^15, otherwise accept if smaller, reject if larger
 | 
			
		||||
    int Qd = (Q >> 237) - r0;
 | 
			
		||||
    if ((Qd < 9125 - 9043) & (va / u < 16)) {
 | 
			
		||||
      x = muldivr(v, 1 << 252, u);    ;; x:=v/u as fixed252; reject immediately if |v/u| >= 16
 | 
			
		||||
      if (Qd >= 0) {   ;; immediately accept if Qd < 0
 | 
			
		||||
        ;; rarely taken branch - 0.012 times per call on average
 | 
			
		||||
        ;; check condition v^2 < -4*u^2*log(u), or equivalent condition u < exp(-x^2/4) for x=v/u
 | 
			
		||||
        int xx = mulrshiftr256(x, x) ~/ 4;   ;; x^2/4 as fixed248
 | 
			
		||||
        int ex = fixed248::exp(- xx) * 16;   ;; exp(-x^2/4) as fixed252
 | 
			
		||||
        if (u > ex) {
 | 
			
		||||
          x = nan();      ;; condition false, reject
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } until (~ is_nan(x));
 | 
			
		||||
  return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
;; generates a random number approximately distributed according to the standard normal distribution
 | 
			
		||||
;; much faster than nrand_f252(), should be suitable for most purposes when only several random numbers are needed
 | 
			
		||||
;; fixed252 nrand_fast();
 | 
			
		||||
int nrand_fast_f252() impure inline_ref {
 | 
			
		||||
  int t = touch(-3) << 253;   ;; -6. as fixed252
 | 
			
		||||
  repeat (12) {
 | 
			
		||||
    t += random() / 16;         ;; add together 12 uniformly random numbers
 | 
			
		||||
  }
 | 
			
		||||
  return t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
;; random number uniformly distributed in [0..1)
 | 
			
		||||
;; fixed248 random();
 | 
			
		||||
int fixed248::random() impure inline {
 | 
			
		||||
  return random() >> 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
;; random number with standard normal distribution
 | 
			
		||||
;; fixed248 nrand();
 | 
			
		||||
int fixed248::nrand() impure inline {
 | 
			
		||||
  return nrand_f252() ~>> 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
;; generates a random number approximately distributed according to the standard normal distribution
 | 
			
		||||
;; fixed248 nrand_fast();
 | 
			
		||||
int fixed248::nrand_fast() impure inline {
 | 
			
		||||
  return nrand_fast_f252() ~>> 4;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,100 +0,0 @@
 | 
			
		|||
{-------------------------- TESTS for mathlib.fc ----------------------------}
 | 
			
		||||
 | 
			
		||||
;; 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_ 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 << 255) - 1 + (1 << 255), (1 << 255) - 1);
 | 
			
		||||
  ;; return geom_mean((1 << 255) - 1, (1 << 255) - 2);
 | 
			
		||||
  ;; 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 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 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 atanh_f258(81877371507464127617551201542979628307507432471243237061821853600756754782485, 36);   ;; 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::exp(fixed248::log(fixed248::Pi_const()) * 3);   ;; Pi^3 ~ 31.006
 | 
			
		||||
  ;; return fixed248::pow(fixed248::Pi_const(), touch(3) << 248);   ;; Pi^3 ~ 31.006, computed more precisely
 | 
			
		||||
  ;; return fixed248::exp(muldivr(fixed248::log(fixed248::Pi_const()), fixed248::Pi_const(), 1 << 248));   ;; Pi^Pi
 | 
			
		||||
  ;; return fixed248::pow(fixed248::Pi_const(), fixed248::Pi_const());   ;; Pi^Pi, more precisely
 | 
			
		||||
  ;; 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
 | 
			
		||||
  int One = touch(1 << 255);
 | 
			
		||||
  ;; 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)
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue