Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - jack

Pages: [1] 2 3
1
Programs / libtommath for Win-64
« on: April 05, 2022, 08:37:27 pm »
made a win64 dll of LibTomMath https://www.libtom.net/
Code: QB64: [Select]
  1.  
  2. Const MP_64BIT = 1
  3. Type private_mp_word
  4.     As String * 128 mpword
  5. Const MP_DIGIT_BIT = 60
  6.  
  7. Type mp_int
  8.     used As Long
  9.     alloc As Long
  10.     sign As Long
  11.     dp As _Offset
  12.  
  13. Declare Dynamic Library "libtommath"
  14.     Function mp_init& (a As mp_int) ' as mp_err
  15.     Function mp_init_size& (a As mp_int, Byval size As Long) ' as mp_err
  16.     Function mp_init_i32& (a As mp_int, Byval b As Long) ' as mp_err
  17.     Function mp_init_l& (a As mp_int, Byval b As Long) ' ' as mp_err
  18.     Function mp_init_u32& (a As mp_int, Byval b As _Unsigned Long) ' as mp_err
  19.     Function mp_init_ul& (a As mp_int, Byval b As _Unsigned Long) ' as mp_err
  20.     Function mp_init_i64& (a As mp_int, Byval b As _Integer64) ' as mp_err
  21.     Function mp_init_ll& (a As mp_int, Byval b As _Integer64) ' as mp_err
  22.     Function mp_init_u64& (a As mp_int, Byval b As _Unsigned _Integer64) ' as mp_err
  23.     Function mp_init_ull& (a As mp_int, Byval b As _Unsigned _Integer64) ' as mp_err
  24.     Function mp_init_set& (a As mp_int, Byval b As _Unsigned _Integer64) ' as mp_err
  25.     Function mp_init_set_int& (a As mp_int, Byval b As _Unsigned Long) ' as mp_err
  26.     Function mp_init_copy (a As mp_int, b As mp_int) ' as mp_err
  27.     Sub mp_clear (a As mp_int)
  28.     Sub mp_exch (a As mp_int, b As mp_int)
  29.     Function mp_shrink& (a As mp_int) ' as mp_err
  30.     Function mp_grow& (a As mp_int, Byval size As Long) ' as mp_err
  31.     Function mp_iseven& (a As mp_int) ' as long
  32.     Function mp_isodd& (a As mp_int) ' as long
  33.     Sub mp_zero (a As mp_int)
  34.     Function mp_get_double# (a As mp_int) ' as double
  35.     Function mp_set_double& (a As mp_int, Byval b As Double) ' as mp_err
  36.     Function mp_get_i32& (a As mp_int) ' as long
  37.     Function mp_get_l& (a As mp_int) ' as long
  38.     Function mp_get_int~& (a As mp_int) ' as ulong
  39.     Function mp_get_long~& (a As mp_int) ' as ulong
  40.     Function mp_get_i64&& (a As mp_int) ' as longint
  41.     Function mp_get_ll&& (a As mp_int) ' as longint
  42.     Function mp_get_long_long~&& (a As mp_int) ' as ulongint
  43.     Sub mp_set_i32 (a As mp_int, Byval b As Long)
  44.     Sub mp_set_l (a As mp_int, Byval b As Long)
  45.     Function mp_set_long& (a As mp_int, Byval b As _Unsigned Long) ' as mp_err
  46.     Sub mp_set_u32 (a As mp_int, Byval b As _Unsigned Long)
  47.     Sub mp_set_ul (a As mp_int, Byval b As _Unsigned Long)
  48.     Function mp_set_int& (a As mp_int, Byval b As _Unsigned Long) ' as mp_err
  49.     Sub mp_set_i64 (a As mp_int, Byval b As _Integer64)
  50.     Function mp_set_long_long& (a As mp_int, Byval b As _Unsigned _Integer64) ' as mp_err
  51.     Sub mp_set_ll (a As mp_int, Byval b As _Integer64)
  52.     Sub mp_set_u64 (a As mp_int, Byval b As _Unsigned _Integer64)
  53.     Sub mp_set_ull (a As mp_int, Byval b As _Unsigned _Integer64)
  54.     Sub mp_set (a As mp_int, Byval b As _Unsigned _Integer64)
  55.     Function mp_get_mag_u32~& (a As mp_int) ' as ulong
  56.     Function mp_get_mag_ul~& (a As mp_int) ' as ulong
  57.     Function mp_get_mag_u64~&& (a As mp_int) ' as ulongint
  58.     Function mp_get_mag_ull~&& (a As mp_int) ' as ulongint
  59.     Function mp_copy (a As mp_int, b As mp_int) ' as mp_err
  60.     Sub mp_clamp (a As mp_int)
  61.     Function mp_export& (rop As _Offset, countp As _Unsigned Long, Byval order As Long, Byval size As _Unsigned Long, Byval endian As Long, Byval nails As _Unsigned Long, op As mp_int) ' as mp_err
  62.     Function mp_import& (rop As mp_int, Byval count As _Unsigned Long, Byval order As Long, Byval size As _Unsigned Long, Byval endian As Long, Byval nails As _Unsigned Long, Byval op As _Offset) ' as mp_err
  63.     Function mp_unpack& (rop As mp_int, Byval count As _Unsigned Long, Byval order As Long, Byval size As _Unsigned Long, Byval endian As Long, Byval nails As _Unsigned Long, op As _Offset) ' as mp_err
  64.     Function mp_pack_count~& (a As mp_int, Byval nails As _Unsigned Long, Byval size As _Unsigned Long) ' as uinteger
  65.     Function mp_pack& (rop As _Offset, Byval maxcount As _Unsigned Long, written As _Unsigned Long, Byval order As Long, Byval size As _Unsigned Long, Byval endian As Long, Byval nails As _Unsigned Long, op As mp_int) ' as mp_err
  66.     Sub mp_rshd (a As mp_int, Byval b As Long)
  67.     Function mp_lshd& (a As mp_int, Byval b As Long) ' as mp_err
  68.     Function mp_div_2d& (a As mp_int, Byval b As Long, c As mp_int, d As mp_int) ' as mp_err
  69.     Function mp_div_2& (a As mp_int, b As mp_int) ' as mp_err
  70.     Function mp_div_3& (a As mp_int, c As mp_int, d As _Unsigned _Integer64) ' as mp_err
  71.     Function mp_mul_2d& (a As mp_int, Byval b As Long, c As mp_int) ' as mp_err
  72.     Function mp_mul_2& (a As mp_int, b As mp_int) ' as mp_err
  73.     Function mp_mod_2d& (a As mp_int, Byval b As Long, c As mp_int) ' as mp_err
  74.     Function mp_2expt& (a As mp_int, Byval b As Long) ' as mp_err
  75.     Function mp_cnt_lsb& (a As mp_int) ' as long
  76.     Function mp_rand& (a As mp_int, Byval digits As Long) ' as mp_err
  77.     Function mp_rand_digit& (r As _Unsigned _Integer64) ' as mp_err
  78.     Function mp_get_bit& (a As mp_int, Byval b As Long) ' as long
  79.     Function mp_tc_xor& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  80.     Function mp_xor& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  81.     Function mp_tc_or& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  82.     Function mp_or& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  83.     Function mp_tc_and& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  84.     Function mp_and& (a As mp_int, b As mp_int, c As mp_int) 'as mp_err
  85.     Function mp_complement& (a As mp_int, b As mp_int) ' as mp_err
  86.     Function mp_tc_div_2d& (a As mp_int, Byval b As Long, c As mp_int) ' as mp_err
  87.     Function mp_signed_rsh& (a As mp_int, Byval b As Long, c As mp_int) ' as mp_err
  88.     Function mp_neg (a As mp_int, b As mp_int) ' as mp_err
  89.     Function mp_abs& (a As mp_int, b As mp_int) ' as mp_err
  90.     Function mp_cmp& (a As mp_int, b As mp_int) 'as mp_ord
  91.     Function mp_cmp_mag& (a As mp_int, b As mp_int) ' as mp_ord
  92.     Function mp_add& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  93.     Function mp_sub& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  94.     Function mp_mul& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  95.     Function mp_sqr& (a As mp_int, b As mp_int) ' as mp_err
  96.     Function mp_div& (a As mp_int, b As mp_int, c As mp_int, d As mp_int) ' as mp_err
  97.     Function mp_mod& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  98.     Function mp_incr& (a As mp_int) ' as mp_err
  99.     Function mp_decr& (a As mp_int) ' as mp_err
  100.     Function mp_cmp_d& (a As mp_int, Byval b As _Unsigned _Integer64) ' as mp_ord
  101.     Function mp_add_d& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int) ' as mp_err
  102.     Function mp_sub_d& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int) ' as mp_err
  103.     Function mp_mul_d& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int) ' as mp_err
  104.     Function mp_div_d& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int, d As _Unsigned _Integer64) ' as mp_err
  105.     Function mp_mod_d& (a As mp_int, Byval b As _Unsigned _Integer64, c As _Unsigned _Integer64) ' as mp_err
  106.     Function mp_addmod& (a As mp_int, b As mp_int, c As mp_int, d As mp_int) ' as mp_err
  107.     Function mp_submod& (a As mp_int, b As mp_int, c As mp_int, d As mp_int) ' as mp_err
  108.     Function mp_mulmod& (a As mp_int, b As mp_int, c As mp_int, d As mp_int) ' as mp_err
  109.     Function mp_sqrmod& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  110.     Function mp_invmod& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  111.     Function mp_gcd& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  112.     Function mp_exteuclid& (a As mp_int, b As mp_int, U1 As mp_int, U2 As mp_int, U3 As mp_int) ' as mp_err
  113.     Function mp_lcm& (a As mp_int, b As mp_int, c As mp_int) ' as mp_err
  114.     Function mp_root_u32& (a As mp_int, Byval b As _Unsigned Long, c As mp_int) ' as mp_err
  115.     Function mp_n_root& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int) ' as mp_err
  116.     Function mp_n_root_ex& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int, Byval fast As Long) ' as mp_err
  117.     Function mp_sqrt& (arg As mp_int, ret As mp_int) ' as mp_err
  118.     Function mp_sqrtmod_prime& (n As mp_int, prime As mp_int, ret As mp_int) ' as mp_err
  119.     Function mp_is_square& (arg As mp_int, ret As Long) ' as mp_err
  120.     Function mp_jacobi& (a As mp_int, n As mp_int, c As Long) ' as mp_err
  121.     Function mp_kronecker& (a As mp_int, p As mp_int, c As Long) ' as mp_err
  122.     Function mp_reduce_setup& (a As mp_int, b As mp_int) ' as mp_err
  123.     Function mp_reduce& (x As mp_int, m As mp_int, mu As mp_int) ' as mp_err
  124.     Function mp_montgomery_setup& (n As mp_int, rho As _Unsigned _Integer64) ' as mp_err
  125.     Function mp_montgomery_calc_normalization& (a As mp_int, b As mp_int) ' as mp_err
  126.     Function mp_montgomery_reduce& (x As mp_int, n As mp_int, Byval rho As _Unsigned _Integer64) ' as mp_err
  127.     Function mp_dr_is_modulus& (a As mp_int) ' as mp_bool
  128.     Sub mp_dr_setup (a As mp_int, d As _Unsigned _Integer64)
  129.     Function mp_dr_reduce& (x As mp_int, n As mp_int, Byval k As _Unsigned _Integer64) ' as mp_err
  130.     Function mp_reduce_is_2k& (a As mp_int) ' as mp_bool
  131.     Function mp_reduce_2k_setup& (a As mp_int, d As _Unsigned _Integer64) ' as mp_err
  132.     Function mp_reduce_2k& (a As mp_int, n As mp_int, Byval d As _Unsigned _Integer64) ' as mp_err
  133.     Function mp_reduce_is_2k_l& (a As mp_int) ' as mp_bool
  134.     Function mp_reduce_2k_setup_l& (a As mp_int, d As mp_int) ' as mp_err
  135.     Function mp_reduce_2k_l& (a As mp_int, n As mp_int, d As mp_int) ' as mp_err
  136.     Function mp_exptmod& (G As mp_int, X As mp_int, P As mp_int, Y As mp_int) ' as mp_err
  137.     Function mp_prime_is_divisible& (a As mp_int, result As Long) ' as mp_err
  138.     Function mp_prime_fermat& (a As mp_int, b As mp_int, result As Long) ' as mp_err
  139.     Function mp_prime_miller_rabin& (a As mp_int, b As mp_int, result As Long) ' as mp_err
  140.     Function mp_prime_rabin_miller_trials& (ByVal size As Long) ' as long
  141.     Function mp_prime_strong_lucas_selfridge& (a As mp_int, result As Long) ' as mp_err
  142.     Function mp_prime_frobenius_underwood& (N As mp_int, result As Long) ' as mp_err
  143.     Function mp_prime_is_prime& (a As mp_int, Byval t As Long, result As Long) ' as mp_err
  144.     Function mp_prime_next_prime& (a As mp_int, Byval t As Long, Byval bbs_style As Long) ' as mp_err
  145.     Function mp_prime_rand& (a As mp_int, Byval t As Long, Byval size As Long, Byval flags As Long) ' as mp_err
  146.     Function mp_log_u32& (a As mp_int, Byval base As _Unsigned Long, c As _Unsigned Long) ' as mp_err
  147.     Function mp_expt_u32& (a As mp_int, Byval b As _Unsigned Long, c As mp_int) ' as mp_err
  148.     Function mp_expt_d& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int) ' as mp_err
  149.     Function mp_expt_d_ex& (a As mp_int, Byval b As _Unsigned _Integer64, c As mp_int, Byval fast As Long) ' as mp_err
  150.     Function mp_count_bits& (a As mp_int) ' as long
  151.     Function mp_unsigned_bin_size& (a As mp_int) ' as long
  152.     Function mp_read_unsigned_bin& (a As mp_int, Byval b As _Offset, Byval c As Long) ' as mp_err
  153.     Function mp_to_unsigned_bin& (a As mp_int, Byval b As _Offset) ' as mp_err
  154.     Function mp_to_unsigned_bin_n& (a As mp_int, Byval b As _Offset, outlen As _Unsigned Long) ' as mp_err
  155.     Function mp_signed_bin_size& (a As mp_int) ' as long
  156.     Function mp_read_signed_bin& (a As mp_int, Byval b As _Offset, Byval c As Long) ' as mp_err
  157.     Function mp_to_signed_bin& (a As mp_int, Byval b As _Offset) ' as mp_err
  158.     Function mp_to_signed_bin_n& (a As mp_int, Byval b As _Offset, outlen As _Unsigned Long) ' as mp_err
  159.     Function mp_ubin_size~&& (a As mp_int) ' as uinteger
  160.     Function mp_from_ubin& (a As mp_int, Byval buf As _Offset, Byval size As _Unsigned _Integer64) ' as mp_err
  161.     Function mp_to_ubin& (a As mp_int, Byval buf As _Offset, Byval maxlen As _Unsigned _Integer64, written As _Unsigned _Integer64) ' as mp_err
  162.     Function mp_sbin_size~&& (a As mp_int) ' as uinteger
  163.     Function mp_from_sbin& (a As mp_int, Byval buf As _Offset, Byval size As _Unsigned _Integer64) ' as mp_err
  164.     Function mp_to_sbin& (a As mp_int, Byval buf As _Offset, Byval maxlen As _Unsigned _Integer64, written As _Unsigned _Integer64) ' as mp_err
  165.     Function mp_to_radix& (a As mp_int, str As String, Byval maxlen As _Unsigned _Integer64, written As _Unsigned _Integer64, Byval radix As Long) ' as mp_err
  166.     Function mp_radix_size& (a As mp_int, Byval radix As Long, size As Long) ' as mp_err
  167.     Function mp_read_radix& (a As mp_int, str As String, Byval radix As Long) ' as mp_err
  168.     Function mp_toradix (a As mp_int, str As String, Byval radix As Long) ' as mp_err
  169.     Function mp_toradix_n& (a As mp_int, str As String, Byval radix As Long, Byval maxlen As Long) ' as mp_err
  170.  
  171. Dim As mp_int n, m, q, r
  172. Dim As Long ok, k
  173. t = Timer(.0001)
  174. If mp_init(n) <> 0 Then Print "failed to initialize"
  175. If mp_init(m) <> 0 Then Print "failed to initiali"
  176. If mp_init(q) <> 0 Then Print "failed to initiali"
  177. If mp_init(r) <> 0 Then Print "failed to initiali"
  178. 'mp_val "2" + String$(100, "0"), n, 10
  179. 'ok = mp_n_root&(n, 2, r)
  180. 'Print mp_str(r, 10)
  181. 'ok = mp_sqrt&(n, m)
  182. 'Print mp_str(m, 10)
  183. mp_set_i32 n, 2 '4784969
  184. ok = mp_expt_u32(n, 1024, n)
  185. 'mp_set_i32 m, 10
  186. 'ok = mp_expt_u32(m, 1000000, m)
  187. 'fib_mod n, m, r
  188. 'mp_set_i32 m, 10
  189. 'ok = mp_expt_u32(m, 999960, m)
  190. 'ok = mp_div(r, m, q, r)
  191. 'Print mp_str(q, 10)
  192. mp_set_i32 m, 10
  193. ok = mp_expt_u32(m, 40, m)
  194. fib_mod n, m, r
  195. Print mp_str(r, 10)
  196. t = Timer(.0001) - t
  197. mp_clear r
  198. mp_clear q
  199. mp_clear m
  200. mp_clear n
  201.  
  202. Sub fib_mod (k As mp_int, m As mp_int, result As mp_int)
  203.     Dim As mp_int x, y, xx, temp, tmp
  204.     Dim As Long ok, cmp, i, bit_length
  205.  
  206.     If mp_init(x) <> 0 Then
  207.         Print "failed to initialize"
  208.         Exit Sub
  209.     End If
  210.     If mp_init(y) <> 0 Then
  211.         Print "failed to initialize"
  212.         Exit Sub
  213.     End If
  214.     If mp_init(xx) <> 0 Then
  215.         Print "failed to initialize"
  216.         Exit Sub
  217.     End If
  218.     If mp_init(temp) <> 0 Then
  219.         Print "failed to initialize"
  220.         Exit Sub
  221.     End If
  222.     If mp_init(tmp) <> 0 Then
  223.         Print "failed to initialize"
  224.         Exit Sub
  225.     End If
  226.  
  227.     mp_set_i32 tmp, 1
  228.     If mp_cmp(k, tmp) <= 0 Then
  229.         Print "mp_cmp(k, tmp) <= 0"
  230.         ok = mp_copy(k, result)
  231.         Exit Sub
  232.     End If
  233.  
  234.     mp_set_i32 x, 1
  235.     mp_set_i32 y, 0
  236.     ok = mp_log_u32(k, 2, bit_length)
  237.     Print "bit_length="; bit_length
  238.     For i = bit_length - 1 To 0 Step -1
  239.         ok = mp_sqr(x, tmp)
  240.         ok = mp_mod(tmp, m, xx)
  241.         ok = mp_mul(x, y, tmp)
  242.         ok = mp_add(tmp, tmp, tmp)
  243.         ok = mp_add(xx, tmp, tmp)
  244.         ok = mp_mod(tmp, m, x)
  245.         ok = mp_sqr(y, tmp)
  246.         ok = mp_add(xx, tmp, tmp)
  247.         ok = mp_mod(tmp, m, y)
  248.         If mp_get_bit(k, i) Then
  249.             ok = mp_copy(x, temp)
  250.             ok = mp_add(x, y, tmp)
  251.             ok = mp_mod(tmp, m, x)
  252.             ok = mp_copy(temp, y)
  253.         End If
  254.     Next
  255.     ok = mp_copy(x, result)
  256.     mp_clear tmp
  257.     mp_clear temp
  258.     mp_clear xx
  259.     mp_clear y
  260.     mp_clear x
  261.  
  262. Function mp_str$ (n As mp_int, radix As Long)
  263.     Dim sresult As String
  264.     Dim As Long status, size
  265.     status = mp_radix_size&(n, radix, size)
  266.     sresult = Space$(size) + Chr$(0)
  267.     status = mp_toradix_n(n, sresult, radix, size)
  268.     If status = 0 Then
  269.         mp_str$ = _Trim$(sresult)
  270.     Else
  271.         mp_str$ = "error in mp_toradix"
  272.     End If
  273.  
  274. Sub mp_val (s As String, n As mp_int, radix As Long)
  275.     Dim value As String
  276.     Dim status As Long
  277.     Dim As Long ok
  278.     value = s + Chr$(0)
  279.     status = mp_read_radix(n, value, radix)
  280.     If status <> 0 Then Print "could not read number"
  281.  

2
Programs / intel decimal math library
« on: April 03, 2022, 11:31:04 am »
here's a small test of the Intel decimal math library https://www.intel.com/content/www/us/en/developer/articles/tool/intel-decimal-floating-point-math-library.html, if there's enough interest I may expand the function declarations
Code: QB64: [Select]
  1.  
  2.     Function __bid_strtod64~&& (s$, Byval ptr&)
  3.     Function add64~&& Alias "__bid64_add" (ByVal x~&&, Byval y~&&, Byval rnd_mode&, flag&)
  4.     Function sub64~&& Alias "__bid64_sub" (ByVal x~&&, Byval y~&&, Byval rnd_mode&, flag&)
  5.     Function mul64~&& Alias "__bid64_mul" (ByVal x~&&, Byval y&&, Byval rnd_mode&, flag&)
  6.     Function div64~&& Alias "__bid64_div" (ByVal x~&&, Byval y~&&, Byval rnd_mode&, flag&)
  7.  
  8.     Function is_equal64& Alias "__bid64_quiet_equal" (ByVal x~&&, Byval y~&&, flag&)
  9.     Function is_less64& Alias "__bid64_quiet_less" (ByVal x~&&, Byval y~&&, flag&)
  10.     Function is_greater64& Alias "__bid64_quiet_greater" (ByVal x~&&, Byval y~&&, flag&)
  11.     Function is_less_equal64& Alias "__bid64_quiet_less_equal" (ByVal x~&&, Byval y~&&, flag&)
  12.     Function is_greater_equal64& Alias "__bid64_quiet_greater_equal" (ByVal x~&&, Byval y~&&, flag&)
  13.     Function is_unequal64& Alias "__bid64_quiet_not_equal" (ByVal x~&&, Byval y~&&, flag&)
  14.     Function isZero64& Alias "__bid64_isZero" (ByVal x~&&)
  15.     Sub __bid64_to_string (ps$, Byval x~&&, pf&)
  16.     Function copy64~&& Alias "__bid64_copy" (ByVal x~&&)
  17.     Function negate64~&& Alias "__bid64_negate" (ByVal x~&&)
  18.     Function abs64~&& Alias "__bid64_abs" (ByVal x~&&)
  19.     Function sqrt64~&& Alias "__bid64_sqrt" (ByVal x~&&, Byval rnd_mode&, flag&)
  20.     Function cbrt64~&& Alias "__bid64_cbrt" (ByVal x~&&, Byval rnd_mode&, flag&)
  21.     Function sin64~&& Alias "__bid64_sin" (ByVal x~&&, Byval rnd_mode&, flag&)
  22.     Function cos64~&& Alias "__bid64_cos" (ByVal x~&&, Byval rnd_mode&, flag&)
  23.     Function tan64~&& Alias "__bid64_tan" (ByVal x~&&, Byval rnd_mode&, flag&)
  24.     Function asin64~&& Alias "__bid64_asin" (ByVal x~&&, Byval rnd_mode&, flag&)
  25.     Function acos64~&& Alias "__bid64_acos" (ByVal x~&&, Byval rnd_mode&, flag&)
  26.     Function atan64~&& Alias "__bid64_atan" (ByVal x~&&, Byval rnd_mode&, flag&)
  27.     Function sinh64~&& Alias "__bid64_sinh" (ByVal x~&&, Byval rnd_mode&, flag&)
  28.     Function cosh64~&& Alias "__bid64_cosh" (ByVal x~&&, Byval rnd_mode&, flag&)
  29.     Function tanh64~&& Alias "__bid64_tanh" (ByVal x~&&, Byval rnd_mode&, flag&)
  30.     Function asinh64~&& Alias "__bid64_asinh" (ByVal x~&&, Byval rnd_mode&, flag&)
  31.     Function acosh64~&& Alias "__bid64_acosh" (ByVal x~&&, Byval rnd_mode&, flag&)
  32.     Function atanh64~&& Alias "__bid64_atanh" (ByVal x~&&, Byval rnd_mode&, flag&)
  33.     Function atan264~&& Alias "__bid64_atan2" (ByVal x~&&, Byval y~&&, Byval rnd_mode&, flag&)
  34.     Function hypot64~&& Alias "__bid64_hypot" (ByVal x~&&, Byval y~&&, Byval rnd_mode&, flag&)
  35.     Function log1064~&& Alias "__bid64_log10" (ByVal x~&&, Byval rnd_mode&, flag&)
  36.     Function exp1064~&& Alias "__bid64_exp10" (ByVal x~&&, Byval rnd_mode&, flag&)
  37.     Function log64~&& Alias "__bid64_log" (ByVal x~&&, Byval rnd_mode&, flag&)
  38.     Function exp64~&& Alias "__bid64_exp" (ByVal x~&&, Byval rnd_mode&, flag&)
  39.     Function pow64~&& Alias "__bid64_pow" (ByVal x~&&, Byval y~&&, Byval rnd_mode&, flag&)
  40.     Function log264~&& Alias "__bid64_log2" (ByVal x~&&, Byval rnd_mode&, flag&)
  41.     Function exp264~&& Alias "__bid64_exp2" (ByVal x~&&, Byval rnd_mode&, flag&)
  42.     Function erf64~&& Alias "__bid64_erf" (ByVal x~&&, Byval rnd_mode&, flag&)
  43.     Function erfc64~&& Alias "__bid64_erfc" (ByVal x~&&, Byval rnd_mode&, flag&)
  44.     Function tgamma64~&& Alias "__bid64_tgamma" (ByVal x~&&, Byval rnd_mode&, flag&)
  45.     Function lgamma64~&& Alias "__bid64_lgamma" (ByVal x~&&, Byval rnd_mode&, flag&)
  46.     Function floor64l& Alias "__bid64_to_int32_floor" (ByVal x~&&, flag&)
  47.     Function ceil64l& Alias "__bid64_to_int32_ceil" (ByVal x~&&, flag&)
  48.     Function floor64ul~& Alias "__bid64_to_uint32_floor" (ByVal x~&&, flag&)
  49.     Function ceil64ul~& Alias "__bid64_to_uint32_ceil" (ByVal x~&&, flag&)
  50.     Function floor64ll~&& Alias "__bid64_to_int64_floor" (ByVal x~&&, flag&)
  51.     Function ceil64ll~&& Alias "__bid64_to_int64_ceil" (ByVal x~&&, flag&)
  52.     Function floor64ull~&& Alias "__bid64_to_uint64_floor" (ByVal x~&&, flag&)
  53.     Function ceil64ull~&& Alias "__bid64_to_uint64_ceil" (ByVal x~&&, flag&)
  54.     Function tosingle64! Alias "__bid64_to_binary32" (ByVal x~&&, Byval rnd_mode&, flag&)
  55.     Function todouble# Alias "__bid64_to_binary64" (ByVal x~&&, Byval rnd_mode&, flag&)
  56.     Function singleto64~&& Alias "__binary32_to_bid64" (ByVal x As Single, Byval rnd_mode&, flag&)
  57.     Function doubleto64~&& Alias "__binary64_to_bid64" (ByVal x As Double, Byval rnd_mode&, flag&)
  58.  
  59. Dim As Long flag, rm
  60.  
  61. rm = 0
  62. i = strto64("-1")
  63. y = strto64("1")
  64. z = strto64(".1")
  65. While is_less_equal64(i, y, flag)
  66.     Print tostring(i)
  67.     i = add64(i, z, rm, flag)
  68.  
  69. Function strto64~&& (s As String)
  70.     Dim As String sn
  71.     sn = s + Chr$(0)
  72.     strto64~&& = __bid_strtod64(sn, 0)
  73.  
  74.     Dim As Long ex, ex1, i, ln
  75.     Dim As String s, sd, sdl, sdr, se, sign
  76.     Dim As _Unsigned _Integer64 one, x
  77.     Dim As Long flag, rm
  78.     If isZero64(z) Then
  79.         tostring = " 0"
  80.         Exit Function
  81.     End If
  82.     rm = 0
  83.     x = z
  84.     one = __bid_strtod64("1.00000000000000000000", 0)
  85.     s = Space$(256)
  86.     __bid64_to_string s, mul64(x, one, 0, flag), flag
  87.     sd = _Trim$(s)
  88.     ln = Len(sd)
  89.     i = InStr(sd, "E")
  90.     sdl = Left$(sd, i - 1)
  91.     ex = Val(Mid$(sd, i + 1))
  92.     ln = Len(sdl)
  93.     If ex = 0 Then
  94.         sd = sdl
  95.     ElseIf ex > 0 Or ex < 0 Then
  96.         ex1 = ln + ex - 2
  97.         If ex1 >= 0 And ex1 < (ln - 1) Then
  98.             sd = Left$(sdl, ex1 + 2) + "." + Mid$(sdl, ex1 + 3)
  99.         ElseIf ex1 < 0 And ex1 > -5 Then
  100.             sign = Left$(sd, 1)
  101.             sd = sign + "0." + String$(Abs(ex1) - 1, "0") + Mid$(sdl, 2)
  102.         Else
  103.             se = _Trim$(Str$(ex1))
  104.             If ex1 > 0 Then
  105.                 se = "+" + se
  106.             End If
  107.             sd = sdl
  108.             sdl = Left$(sd, 2)
  109.             sdr = Mid$(sd, 3)
  110.             sd = sdl + "." + sdr + "E" + se
  111.         End If
  112.     End If
  113.     If Left$(sd, 1) = "+" Then
  114.         sd = " " + Mid$(sd, 2)
  115.     End If
  116.     tostring = sd
  117.  
here's the 64-bit dll

3
Programs / first & last digits of Fib 2^32
« on: March 05, 2022, 05:59:42 pm »
see https://rosettacode.org/wiki/Fibonacci_matrix-exponentiation
due to the limits of double and integer I present a version that computes the first 7 and last 9 digits of fib 2^32
Code: QB64: [Select]
  1. _Title "Fibon"
  2.  
  3. fn = 4294967296 '2^32
  4. m = 1000000000 '10^9
  5.  
  6. 'using the Binet formula for the Fib number  ( ( (1+sqr(5))/2 )^n - ( (1-sqr(5))/2 )^n )/sqr(5)
  7. 'the apprximation of which is the nearest integer of ( ((1+sqr(5))/2)^n )/sqr(5)
  8. 'we take the Log10 of the last expression log10((1+sqr(5))/2)*n)-log10(sqr(5)
  9. '10^FractionalPart is approximately equal the the fib number, the integer part is the exponent
  10. f = ((Log((1 + Sqr(5)) / 2) * fn) - Log(Sqr(5))) / Log(10)
  11. f = f - Fix(f) 'Fractional part
  12. f = 10## ^ f
  13. s = _Trim$(Str$(f))
  14. c = InStr(s, ".")
  15. s = Left$(s, c - 1) + Mid$(s, c + 1)
  16. s = Left$(s, 7)
  17. last9 = fib(fn, m)
  18. Print "the first"; Len(s); " digits of Fibonacci "; fn; " are "; s
  19. Print "the last"; Len(_Trim$(Str$(last9))); " digits of Fibonacci "; fn; " are "; last9
  20.  
  21.     Dim As _Unsigned _Integer64 b, x, y, xx, temp
  22.     Dim As Long i, bit_length
  23.     If k <= 1 Then
  24.         fib = k
  25.         Exit Function
  26.     End If
  27.     b = k
  28.     x = 1: y = 0
  29.     bit_length = Fix(Log(k) / Log(2)) 'Log2(n) giges the highest bit set of an integer
  30.     For i = bit_length - 1 To 0 Step -1
  31.         xx = x * x Mod m
  32.         x = (xx + 2 * x * y) Mod m
  33.         y = (xx + y * y) Mod m
  34.         If b And 1 Then 'if the least significant bit is 1 then
  35.             temp = x
  36.             x = (x + y) Mod m
  37.             y = temp
  38.         End If
  39.         b = b \ 2 'chop off the least significant bit for the next test
  40.     Next
  41.     fib = x
  42.  

4
QB64 Discussion / QB64 interoperability with FreeBasic
« on: January 24, 2022, 02:52:12 am »
in reference to https://qb64forum.alephc.xyz/index.php?topic=4585.msg139931#msg139931
it took bplus 4 hours to calculate the result, I tried it using the decfloat routines that I wrote in QB64 but after 4 hours I aborted the program, then I tried it with the Freebasic version and the result was calculated and printed to the console in .3 seconds, that's less than half a second
so I was thinking of making a dll in FreeBasic to be used in QB64 to that end I experimented passing a structure that contains a string, I succeeded in figuring out how to get the value from the string but when I tried the same method on just a string it failed
if a string is an element of a structure it's passed by reference but when a simple string is passed then it's passed by value as in char * but in a structure the first element of the string is a pointer to the string data followed by the string length

5
QB64 Discussion / associativity of the exponential operator
« on: January 21, 2022, 10:35:37 am »
QB64 and other Basics treat the ^ operator as left-associative while other programming languages that have an exponentiation operator treat it as right-associative, for example Python and FORTRAN
doing a web search is inconclusive some assert that there's no consensus  whether it should be left or right associative while other state that it's right-associative
Mathematica and Maxima treats it as right-associative while Maple gives the error message that the power operator is non-associative
from a mathematical perspective which is right? non-associative or right-associative?

6
Programs / just for amusement, rounding error
« on: November 20, 2021, 10:42:59 am »
in the book "Handbook of Floating-Point Arithmetic" by Jean-Michel Muller and others, page 10
shows an interesting example, if you google for the afore mentioned book you may find a pdf of the same
Code: QB64: [Select]
  1. Dest Console
  2.  
  3. Option Explicit
  4.  
  5. Dim As Double i, account, euler
  6. Dim As Long j, n
  7.  
  8. n = 25
  9. Dim As Double approximate_value(25)
  10. For i = 1 To 25
  11.     Read approximate_value(i)
  12. euler = 2.7182818284590452353602874713527#
  13. Print "Exact value = n! * e - int(e * n!) where e = 2.718281828459045..."
  14. Print "  n  Approximate value         computed"
  15. For j = 1 To 25
  16.     account = euler - 1#
  17.     For i = 1 To j
  18.         account = i * account - 1
  19.     Next
  20.     Print Using "###"; j;
  21.     Print approximate_value(j), account
  22. Data .7182818284590452#
  23. Data .4365636569180905#
  24. Data .3096909707542714#
  25. Data .2387638830170856#
  26. Data .1938194150854282#
  27. Data .1629164905125695#
  28. Data .1404154335879862#
  29. Data .1233234687038897#
  30. Data .1099112183350075#
  31. Data .0991121833500754#
  32. Data .0902340168508295#
  33. Data .0828082022099543#
  34. Data .0765066287294056#
  35. Data .0710928022116781#
  36. Data .0663920331751714#
  37. Data .0622725308027424#
  38. Data .0586330236466206#
  39. Data .0553944256391715#
  40. Data .0524940871442588#
  41. Data .0498817428851762#
  42. Data .0475166005887012#
  43. Data .0453652129514256#
  44. Data .0433998978827887#
  45. Data .0415975491869292#
  46. Data .0399387296732302#
  47.  
output
Code: [Select]
Exact value = n! * e - int(e * n!) where e = 2.718281828459045...
  n  Approximate value         computed
  1 .7182818284590452         .7182818284590451
  2 .4365636569180905         .4365636569180902
  3 .3096909707542714         .3096909707542705
  4 .2387638830170856         .2387638830170822
  5 .1938194150854282         .193819415085411
  6 .1629164905125695         .1629164905124654
  7 .1404154335879862         .1404154335872576
  8 .1233234687038897         .123323468698061
  9 .1099112183350075         .109911218282548
 10 9.911218335007541D-02     9.911218282547907D-02
 11 .0902340168508295         9.023401108026974D-02
 12 .0828082022099543         8.280813296323686D-02
 13 .0765066287294056         7.650572852207915D-02
 14 .0710928022116781         7.108019930910814D-02
 15 .0663920331751714         6.620298963662208D-02
 16 .0622725308027424         5.924783418595325D-02
 17 .0586330236466206         7.213181161205284D-03
 18 .0553944256391715        -.870162739098305
 19 .0524940871442588        -17.5330920428678
 20 .0498817428851762        -351.661840857356
 21 .0475166005887012        -7385.898658004473
 22 .0453652129514256        -162490.7704760984
 23 .0433998978827887        -3737288.720950264
 24 .0415975491869292        -89694930.30280632
 25 .0399387296732302        -2242373258.570158

7
Programs / Concatenation Coincidence
« on: October 30, 2021, 03:19:29 pm »
reference https://projecteuler.net/problem=751
Code: QB64: [Select]
  1. Dest Console
  2.  
  3. Option Explicit
  4. Dim As Float b
  5. Dim As Integer64 a
  6. Dim As Long i, j
  7. Dim As String s, s1, s2
  8.  
  9. s = "2."
  10. b = Val(s)
  11. For i = 1 To 14 Step 2
  12.     For j = 1 To i + 2
  13.         a = Fix(b)
  14.         'Print a
  15.         b = Fix(b) * (b - Fix(b) + 1)
  16.         s1 = s2
  17.         s2 = Str$(a)
  18.     Next
  19.     s = s + Trim$(s1) + Trim$(s2)
  20.     b = Val(s)
  21. Print s; " to "; Len(s) - 2; " places"
  22. b = Val(s)
  23. For i = 1 To 15
  24.     a = Fix(b)
  25.     Print a; " ";
  26.     b = Fix(b) * (b - Fix(b) + 1)
  27.  
output
Code: [Select]
2.223561019313554106173177195 to  27  places
 2   2   2   3   5   6   10   19   31   35   54   106   173   177   195

8
QB64 Discussion / String to BSTR and back
« on: October 20, 2021, 11:34:41 am »
has anyone coded routines to convert a string to BSTR and vice-versa? https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr

9
Programs / decfloat 2.0
« on: October 10, 2021, 08:00:41 am »
FreeBASIC supports arrays in UDT's and I had written this using arrays in the decfloat type
so in order to test how much slower this routines would perform using a string * some_number
I rewrote it using the same string scheme as you see here, for 1000 digit precision it was 178 times slower
Code: QB64: [Select]
  1. Dest Console
  2.  
  3. Option Explicit
  4.  
  5. Const NUMBER_OF_DIGITS = 512
  6. Const NUM_DIGITS = NUMBER_OF_DIGITS
  7. Const NUM_DWORDS = NUM_DIGITS \ 8
  8. Const BIAS = 1073741824 '2 ^ 30
  9. Const MANTISSA_BYTES = (NUM_DWORDS + 1) * 8 * 4
  10.  
  11. Type decfloat
  12.     As Long sign
  13.     As Unsigned Long exponent
  14.     As String * Mantissa_bytes mantissa
  15.  
  16. ' Error definitions
  17.  
  18. Const DIVZ_ERR = 1 'Divide by zero
  19. Const EXPO_ERR = 2 'Exponent overflow error
  20. Const EXPU_ERR = 3 'Exponent underflow error
  21. Dim Shared As decfloat pi_dec
  22. Call pi_brent_salamin(pi_dec, NUMBER_OF_DIGITS)
  23.  
  24. Dim As decfloat n, m, z
  25.  
  26. t = Timer
  27. Call fpfactorial(z, 10000, NUMBER_OF_DIGITS)
  28. t = Timer - t
  29. Print "factorial(10000) to "; NUMBER_OF_DIGITS; " digits"
  30. Print fp2str(z, NUMBER_OF_DIGITS)
  31. Print "in "; t; " seconds"
  32. Call str2fp(n, "3")
  33. Call str2fp(m, "9")
  34. t = Timer
  35. Call fpdiv(z, n, m, NUMBER_OF_DIGITS)
  36. t = Timer - t
  37. Print "3/9 to "; NUMBER_OF_DIGITS; " digits"
  38. Print fp2str(z, NUMBER_OF_DIGITS)
  39. Print "in "; t; " seconds"
  40. t = Timer
  41. Call fpmul(z, z, z, NUMBER_OF_DIGITS)
  42. t = Timer - t
  43. Print "and square it"
  44. Print fp2str(z, NUMBER_OF_DIGITS)
  45. Call str2fp(n, "2")
  46. t = Timer
  47. Call fplog(z, n, NUMBER_OF_DIGITS)
  48. t = Timer - t
  49. Print "ln(2) to "; NUMBER_OF_DIGITS; " digits"
  50. Print fp2str(z, NUMBER_OF_DIGITS)
  51. Print "in "; t; " seconds"
  52. t = Timer
  53. Call fpexp(z, z, NUMBER_OF_DIGITS)
  54. t = Timer - t
  55. Print "and the inverse"
  56. Print fp2str(z, NUMBER_OF_DIGITS)
  57. Print "in "; t; " seconds"
  58. Call si2fp(n, 3, NUMBER_OF_DIGITS)
  59. Print "reciprocal of 3"
  60. t = Timer
  61. Call fpinv(z, n, NUMBER_OF_DIGITS)
  62. t = Timer - t
  63. Print fp2str(z, NUMBER_OF_DIGITS)
  64. Print "in "; t; " seconds"
  65.  
  66. Sub set (s$, i&, v~&)
  67.     Mid$(s$, 4 * i& + 1, 4) = MKL$(v~&)
  68.  
  69. Function git~& (s$, i&)
  70.     git = CVL(Mid$(s$, 4 * i& + 1, 4))
  71.  
  72. Function fp2str_exp$ (n As decfloat, places As Long)
  73.     Dim As Long i, ex
  74.     Dim As String v, f, ts
  75.     If n.exponent > 0 Then
  76.         ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
  77.     Else
  78.         ex = 0
  79.     End If
  80.     If n.sign Then v = "-" Else v = " "
  81.     ts = Str$(git(n.mantissa, 0))
  82.     ts = Trim$(ts)
  83.     If Len(ts) < 8 Then
  84.         ts = ts + String$(8 - Len(ts), "0")
  85.     End If
  86.     v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
  87.     For i = 1 To NUM_DWORDS - 1
  88.         ts = Str$(git(n.mantissa, i))
  89.         ts = Trim$(ts)
  90.         If Len(ts) < 8 Then
  91.             ts = String$(8 - Len(ts), "0") + ts
  92.         End If
  93.         v = v + ts
  94.     Next
  95.     v = Left$(v, places + 3)
  96.     f = Trim$(Str$(Abs(ex)))
  97.     f = String$(5 - Len(f), "0") + f
  98.     If ex < 0 Then v = v + "E-" Else v = v + "E+"
  99.     v = v + f
  100.     fp2str_exp$ = v
  101.  
  102. 'long part of num
  103. Sub fpfix (result As decfloat, num As decfloat)
  104.     Dim As decfloat ip
  105.     Dim As Long ex, ex2, j, k
  106.  
  107.     ex = (num.exponent And &H7FFFFFFF) - BIAS
  108.     If ex < 1 Then
  109.         result = ip: Exit Sub
  110.     End If
  111.     If ex >= (NUM_DIGITS) Then
  112.         result = num: Exit Sub
  113.     End If
  114.     ex2 = ex \ 8
  115.     k = ex2
  116.     j = ex Mod 8
  117.     While ex2 > 0
  118.         ex2 = ex2 - 1
  119.         Call set(ip.mantissa, ex2, git(num.mantissa, ex2))
  120.     Wend
  121.     If j = 1 Then
  122.         Call set(ip.mantissa, k, 10000000 * (git(num.mantissa, k) \ 10000000))
  123.     ElseIf j = 2 Then
  124.         Call set(ip.mantissa, k, 1000000 * (git(num.mantissa, k) \ 1000000))
  125.     ElseIf j = 3 Then
  126.         Call set(ip.mantissa, k, 100000 * (git(num.mantissa, k) \ 100000))
  127.     ElseIf j = 4 Then
  128.         Call set(ip.mantissa, k, 10000 * (git(num.mantissa, k) \ 10000))
  129.     ElseIf j = 5 Then
  130.         Call set(ip.mantissa, k, 1000 * (git(num.mantissa, k) \ 1000))
  131.     ElseIf j = 6 Then
  132.         Call set(ip.mantissa, k, 100 * (git(num.mantissa, k) \ 100))
  133.     ElseIf j = 7 Then
  134.         Call set(ip.mantissa, k, 10 * (git(num.mantissa, k) \ 10))
  135.     ElseIf j = 8 Then
  136.         Call set(ip.mantissa, k, git(num.mantissa, k))
  137.     End If
  138.     ip.exponent = ex + BIAS
  139.     ip.sign = num.sign
  140.     result = ip
  141.  
  142. Function fp2dbl# (n As decfloat)
  143.     Dim As Long ex
  144.     Dim As String v, f, ts
  145.     If n.exponent > 0 Then
  146.         ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
  147.     Else
  148.         ex = 0
  149.     End If
  150.     If n.sign Then v = "-" Else v = " "
  151.     ts = Trim$(Str$(git(n.mantissa, 0)))
  152.     If Len(ts) < 8 Then
  153.         ts = ts + String$(8 - Len(ts), "0")
  154.     End If
  155.     v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
  156.     ts = Trim$(Str$(git(n.mantissa, 1)))
  157.     If Len(ts) < 8 Then
  158.         ts = String$(8 - Len(ts), "0") + ts
  159.     End If
  160.     v = v + ts
  161.  
  162.     f = Str$(Abs(ex))
  163.     f = String$(5 - Len(f), "0") + f
  164.     If ex < 0 Then v = v + "E-" Else v = v + "E+"
  165.     v = v + f
  166.     fp2dbl# = Val(v)
  167.  
  168. Function fp2str_fix$ (n As decfloat, places As Long)
  169.     Dim As Long i, ex
  170.     Dim As String v, ts, s
  171.     If n.exponent > 0 Then
  172.         ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
  173.     Else
  174.         ex = 0
  175.     End If
  176.     If n.sign Then s = "-" Else s = " "
  177.     ts = Trim$(Str$(git(n.mantissa, 0)))
  178.     If Len(ts) < 8 Then
  179.         ts = ts + String$(8 - Len(ts), "0")
  180.     End If
  181.     v = ts
  182.     For i = 1 To NUM_DWORDS - 1
  183.         ts = Trim$(Str$(git(n.mantissa, i)))
  184.         If Len(ts) < 8 Then
  185.             ts = String$(8 - Len(ts), "0") + ts
  186.         End If
  187.         v = v + ts
  188.     Next
  189.     If places < NUM_DIGITS Then
  190.         v = Left$(v, places)
  191.     End If
  192.     If ex = 0 Then
  193.         v = Left$(v, 1) + "." + Mid$(v, 2)
  194.     ElseIf ex < 0 Then
  195.         v = "0." + String$(Abs(ex) - 1, "0") + v
  196.     ElseIf ex > 0 Then
  197.         v = Left$(v, ex + 1) + "." + Mid$(v, ex + 2)
  198.     End If
  199.     fp2str_fix$ = s + v
  200.  
  201. Function fp2str$ (n As decfloat, places As Long)
  202.     Dim As Long ex
  203.     If n.exponent > 0 Then
  204.         ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
  205.     Else
  206.         ex = 0
  207.     End If
  208.     If Abs(ex) < places Then
  209.         fp2str = fp2str_fix(n, places)
  210.     Else
  211.         fp2str = fp2str_exp(n, places)
  212.     End If
  213.  
  214. Sub str2fp (result As decfloat, value As String)
  215.     Dim As Long j, s, d, e, ep, ex, es, i, f, fp, fln
  216.     Dim As String c, f1, f2, f3, ts
  217.     Dim As Unsigned Long ulng
  218.     Dim n As decfloat
  219.     j = 1
  220.     s = 1
  221.     d = 0
  222.     e = 0
  223.     ep = 0
  224.     ex = 0
  225.     es = 1
  226.     i = 0
  227.     f = 0
  228.     fp = 0
  229.     f1 = ""
  230.     f2 = ""
  231.     f3 = ""
  232.     value = UCase$(value)
  233.     fln = Len(value)
  234.  
  235.     While j <= fln
  236.         c = Mid$(value, j, 1)
  237.         If ep = 1 Then
  238.             If c = " " Then
  239.                 j = j + 1
  240.                 GoTo skip_while
  241.             End If
  242.             If c = "-" Then
  243.                 es = -es
  244.                 c = ""
  245.             End If
  246.             If c = "+" Then
  247.                 j = j + 1
  248.                 GoTo skip_while
  249.             End If
  250.             If (c = "0") And (f3 = "") Then
  251.                 j = j + 1
  252.                 GoTo skip_while
  253.             End If
  254.             If (c > "/") And (c < ":") Then 'c is digit between 0 and 9
  255.                 f3 = f3 + c
  256.                 ex = 10 * ex + (Asc(c) - 48)
  257.                 j = j + 1
  258.                 GoTo skip_while
  259.             End If
  260.         End If
  261.  
  262.         If c = " " Then
  263.             j = j + 1
  264.             GoTo skip_while
  265.         End If
  266.         If c = "-" Then
  267.             s = -s
  268.             j = j + 1
  269.             GoTo skip_while
  270.         End If
  271.         If c = "+" Then
  272.             j = j + 1
  273.             GoTo skip_while
  274.         End If
  275.         If c = "." Then
  276.             If d = 1 Then
  277.                 j = j + 1
  278.                 GoTo skip_while
  279.             End If
  280.             d = 1
  281.         End If
  282.         If (c > "/") And (c < ":") Then 'c is digit between 0 and 9
  283.             If ((c = "0") And (i = 0)) Then
  284.                 If d = 0 Then
  285.                     j = j + 1
  286.                     GoTo skip_while
  287.                 End If
  288.                 If (d = 1) And (f = 0) Then
  289.                     e = e - 1
  290.                     j = j + 1
  291.                     GoTo skip_while
  292.                 End If
  293.             End If
  294.             If d = 0 Then
  295.                 f1 = f1 + c
  296.                 i = i + 1
  297.             Else
  298.                 If (c > "0") Then
  299.                     fp = 1
  300.                 End If
  301.                 f2 = f2 + c
  302.                 f = f + 1
  303.             End If
  304.         End If
  305.         If c = "E" Or c = "D" Then
  306.             ep = 1
  307.         End If
  308.         j = j + 1
  309.         skip_while:
  310.     Wend
  311.     If fp = 0 Then
  312.         f = 0
  313.         f2 = ""
  314.     End If
  315.  
  316.     If s = -1 Then s = &H8000 Else s = 0
  317.     n.sign = s
  318.     ex = es * ex - 1 + i + e
  319.     f1 = f1 + f2
  320.     f1 = Mid$(f1, 1, 1) + Right$(f1, Len(f1) - 1)
  321.     fln = Len(f1)
  322.     If Len(f1) > (NUM_DIGITS + 1 + 8) Then
  323.         f1 = Mid$(f1, 1, (NUM_DIGITS + 1 + 8))
  324.     End If
  325.     While Len(f1) < (NUM_DIGITS + 1 + 8)
  326.         f1 = f1 + "0"
  327.     Wend
  328.     j = 1
  329.     For i = 0 To NUM_DWORDS
  330.         ts = Mid$(f1, j, 8)
  331.         ulng = Val(ts)
  332.         Call set(n.mantissa, i, ulng)
  333.         If ulng <> 0 Then fp = 1
  334.         j = j + 8
  335.     Next
  336.     If fp Then n.exponent = (ex + BIAS + 1) Else n.exponent = 0
  337.     result = n
  338.  
  339. Sub si2fp (result As decfloat, m As Integer64, digits_in As Long)
  340.     Dim As Long digits
  341.     digits = digits_in
  342.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  343.     Dim As decfloat fac1
  344.     Dim As Long i
  345.     Dim As Integer64 n
  346.     n = Abs(m)
  347.  
  348.     If n > 9999999999999999 Then
  349.         Call str2fp(fac1, Str$(m))
  350.         result = fac1: Exit Sub
  351.     End If
  352.  
  353.     For i = 1 To digits
  354.         Call set(fac1.mantissa, i, 0)
  355.     Next
  356.  
  357.     If m = 0 Then
  358.         fac1.exponent = 0
  359.         fac1.sign = 0
  360.         result = fac1: Exit Sub
  361.     End If
  362.  
  363.     fac1.exponent = BIAS
  364.     If n < 100000000 Then
  365.         If n < 10 Then
  366.             Call set(fac1.mantissa, 0, n * 10000000)
  367.             fac1.exponent = fac1.exponent + 1
  368.         ElseIf n < 100 Then
  369.             Call set(fac1.mantissa, 0, n * 1000000)
  370.             fac1.exponent = fac1.exponent + 2
  371.         ElseIf n < 1000 Then
  372.             Call set(fac1.mantissa, 0, n * 100000)
  373.             fac1.exponent = fac1.exponent + 3
  374.         ElseIf n < 10000 Then
  375.             Call set(fac1.mantissa, 0, n * 10000)
  376.             fac1.exponent = fac1.exponent + 4
  377.         ElseIf n < 100000 Then
  378.             Call set(fac1.mantissa, 0, n * 1000)
  379.             fac1.exponent = fac1.exponent + 5
  380.         ElseIf n < 1000000 Then
  381.             Call set(fac1.mantissa, 0, n * 100)
  382.             fac1.exponent = fac1.exponent + 6
  383.         ElseIf n < 10000000 Then
  384.             Call set(fac1.mantissa, 0, n * 10)
  385.             fac1.exponent = fac1.exponent + 7
  386.         ElseIf n < 100000000 Then
  387.             Call set(fac1.mantissa, 0, n)
  388.             fac1.exponent = fac1.exponent + 8
  389.         End If
  390.     End If
  391.     If n > 99999999 Then
  392.         fac1.exponent = fac1.exponent + 8
  393.         If n < 1000000000 Then
  394.             Call set(fac1.mantissa, 0, n \ 10)
  395.             Call set(fac1.mantissa, 1, (n Mod 10) * 10000000)
  396.             fac1.exponent = fac1.exponent + 1
  397.         ElseIf n < 100000000000 Then
  398.             Call set(fac1.mantissa, 0, n \ 100)
  399.             Call set(fac1.mantissa, 1, (n Mod 100) * 1000000)
  400.             fac1.exponent = fac1.exponent + 2
  401.         ElseIf n < 1000000000000 Then
  402.             Call set(fac1.mantissa, 0, n \ 1000)
  403.             Call set(fac1.mantissa, 1, (n Mod 1000) * 100000)
  404.             fac1.exponent = fac1.exponent + 3
  405.         ElseIf n < 10000000000000 Then
  406.             Call set(fac1.mantissa, 0, n \ 10000)
  407.             Call set(fac1.mantissa, 1, (n Mod 10000) * 10000)
  408.             fac1.exponent = fac1.exponent + 4
  409.         ElseIf n < 100000000000000 Then
  410.             Call set(fac1.mantissa, 0, n \ 100000)
  411.             Call set(fac1.mantissa, 1, (n Mod 100000) * 1000)
  412.             fac1.exponent = fac1.exponent + 5
  413.         ElseIf n < 1000000000000000 Then
  414.             Call set(fac1.mantissa, 0, n \ 1000000)
  415.             Call set(fac1.mantissa, 1, (n Mod 1000000) * 100)
  416.             fac1.exponent = fac1.exponent + 6
  417.         ElseIf n < 10000000000000000 Then
  418.             Call set(fac1.mantissa, 0, n \ 10000000)
  419.             Call set(fac1.mantissa, 1, (n Mod 10000000) * 10)
  420.             fac1.exponent = fac1.exponent + 7
  421.         ElseIf n < 100000000000000000 Then
  422.             Call set(fac1.mantissa, 0, n \ 100000000)
  423.             Call set(fac1.mantissa, 1, n Mod 100000000)
  424.             fac1.exponent = fac1.exponent + 8
  425.         End If
  426.     End If
  427.     If m < 0 Then
  428.         fac1.sign = &H8000
  429.     Else
  430.         fac1.sign = 0
  431.     End If
  432.     result = fac1
  433.  
  434. Sub RSHIFT_1 (mantissa As decfloat, digits_in As Long)
  435.     Dim As Long digits
  436.     digits = digits_in
  437.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  438.  
  439.     Dim As Unsigned Long v1, v2
  440.     Dim As Long i
  441.     For i = digits To 1 Step -1
  442.         v1 = git(mantissa.mantissa, i) \ 10
  443.         v2 = git(mantissa.mantissa, i - 1) Mod 10
  444.         v2 = v2 * 10000000 + v1
  445.         Call set(mantissa.mantissa, i, v2)
  446.     Next
  447.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 10)
  448.  
  449. Sub LSHIFT_1 (mantissa As decfloat, digits_in As Long)
  450.     Dim As Long digits
  451.     digits = digits_in
  452.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  453.  
  454.     Dim As Unsigned Long v1, v2
  455.     Dim As Long i
  456.     For i = 0 To digits - 1
  457.         v1 = git(mantissa.mantissa, i) Mod 10000000
  458.         v2 = git(mantissa.mantissa, i + 1) \ 10000000
  459.         Call set(mantissa.mantissa, i, v1 * 10 + v2)
  460.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 10000000)
  461.     Next
  462.     Call set(mantissa.mantissa, digits, 10 * (git(mantissa.mantissa, digits) Mod 10000000))
  463.  
  464. Sub RSHIFT_2 (mantissa As decfloat, digits_in As Long)
  465.     Dim As Long digits
  466.     digits = digits_in
  467.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  468.  
  469.     Dim As Unsigned Long v1, v2
  470.     Dim As Long i
  471.     For i = digits To 1 Step -1
  472.         v1 = git(mantissa.mantissa, i) \ 100
  473.         v2 = git(mantissa.mantissa, i - 1) Mod 100
  474.         v2 = v2 * 1000000 + v1
  475.         Call set(mantissa.mantissa, i, v2)
  476.     Next
  477.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 100)
  478.  
  479. Sub LSHIFT_2 (mantissa As decfloat, digits_in As Long)
  480.     Dim As Long digits
  481.     digits = digits_in
  482.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  483.  
  484.     Dim As Unsigned Long v1, v2
  485.     Dim As Long i
  486.     For i = 0 To digits - 1
  487.         v1 = git(mantissa.mantissa, i) Mod 1000000
  488.         v2 = git(mantissa.mantissa, i + 1) \ 1000000
  489.         Call set(mantissa.mantissa, i, v1 * 100 + v2)
  490.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 1000000)
  491.     Next
  492.     Call set(mantissa.mantissa, digits, 100 * (git(mantissa.mantissa, digits) Mod 1000000))
  493.  
  494. Sub RSHIFT_3 (mantissa As decfloat, digits_in As Long)
  495.     Dim As Long digits
  496.     digits = digits_in
  497.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  498.  
  499.     Dim As Unsigned Long v1, v2
  500.     Dim As Long i
  501.     For i = digits To 1 Step -1
  502.         v1 = git(mantissa.mantissa, i) \ 1000
  503.         v2 = git(mantissa.mantissa, i - 1) Mod 1000
  504.         v2 = v2 * 100000 + v1
  505.         Call set(mantissa.mantissa, i, v2)
  506.     Next
  507.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 1000)
  508.  
  509. Sub LSHIFT_3 (mantissa As decfloat, digits_in As Long)
  510.     Dim As Long digits
  511.     digits = digits_in
  512.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  513.  
  514.     Dim As Unsigned Long v1, v2
  515.     Dim As Long i
  516.     For i = 0 To digits - 1
  517.         v1 = git(mantissa.mantissa, i) Mod 100000
  518.         v2 = git(mantissa.mantissa, i + 1) \ 100000
  519.         Call set(mantissa.mantissa, i, v1 * 1000 + v2)
  520.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 100000)
  521.     Next
  522.     Call set(mantissa.mantissa, digits, 1000 * (git(mantissa.mantissa, digits) Mod 100000))
  523.  
  524. Sub RSHIFT_4 (mantissa As decfloat, digits_in As Long)
  525.     Dim As Long digits
  526.     digits = digits_in
  527.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  528.  
  529.     Dim As Unsigned Long v1, v2
  530.     Dim As Long i
  531.     For i = digits To 1 Step -1
  532.         v1 = git(mantissa.mantissa, i) \ 10000
  533.         v2 = git(mantissa.mantissa, i - 1) Mod 10000
  534.         v2 = v2 * 10000 + v1
  535.         Call set(mantissa.mantissa, i, v2)
  536.     Next
  537.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 10000)
  538.  
  539. Sub LSHIFT_4 (mantissa As decfloat, digits_in As Long)
  540.     Dim As Long digits
  541.     digits = digits_in
  542.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  543.  
  544.     Dim As Unsigned Long v1, v2
  545.     Dim As Long i
  546.     For i = 0 To digits - 1
  547.         v1 = git(mantissa.mantissa, i) Mod 10000
  548.         v2 = git(mantissa.mantissa, i + 1) \ 10000
  549.         Call set(mantissa.mantissa, i, v1 * 10000 + v2)
  550.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 10000)
  551.     Next
  552.     Call set(mantissa.mantissa, digits, 10000 * (git(mantissa.mantissa, digits) Mod 10000))
  553.  
  554. Sub RSHIFT_5 (mantissa As decfloat, digits_in As Long)
  555.     Dim As Long digits
  556.     digits = digits_in
  557.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  558.  
  559.     Dim As Unsigned Long v1, v2
  560.     Dim As Long i
  561.     For i = digits To 1 Step -1
  562.         v1 = git(mantissa.mantissa, i) \ 100000
  563.         v2 = git(mantissa.mantissa, i - 1) Mod 100000
  564.         v2 = v2 * 1000 + v1
  565.         Call set(mantissa.mantissa, i, v2)
  566.     Next
  567.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 100000)
  568.  
  569. Sub LSHIFT_5 (mantissa As decfloat, digits_in As Long)
  570.     Dim As Long digits
  571.     digits = digits_in
  572.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  573.  
  574.     Dim As Unsigned Long v1, v2
  575.     Dim As Long i
  576.     For i = 0 To digits - 1
  577.         v1 = git(mantissa.mantissa, i) Mod 1000
  578.         v2 = git(mantissa.mantissa, i + 1) \ 1000
  579.         Call set(mantissa.mantissa, i, v1 * 100000 + v2)
  580.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 1000)
  581.     Next
  582.     Call set(mantissa.mantissa, digits, 100000 * (git(mantissa.mantissa, digits) Mod 1000))
  583.  
  584. Sub RSHIFT_6 (mantissa As decfloat, digits_in As Long)
  585.     Dim As Long digits
  586.     digits = digits_in
  587.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  588.  
  589.     Dim As Unsigned Long v1, v2
  590.     Dim As Long i
  591.     For i = digits To 1 Step -1
  592.         v1 = git(mantissa.mantissa, i) \ 1000000
  593.         v2 = git(mantissa.mantissa, i - 1) Mod 1000000
  594.         v2 = v2 * 100 + v1
  595.         Call set(mantissa.mantissa, i, v2)
  596.     Next
  597.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 1000000)
  598.  
  599. Sub LSHIFT_6 (mantissa As decfloat, digits_in As Long)
  600.     Dim As Long digits
  601.     digits = digits_in
  602.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  603.  
  604.     Dim As Unsigned Long v1, v2
  605.     Dim As Long i
  606.     For i = 0 To digits - 1
  607.         v1 = git(mantissa.mantissa, i) Mod 100
  608.         v2 = git(mantissa.mantissa, i + 1) \ 100
  609.         Call set(mantissa.mantissa, i, v1 * 1000000 + v2)
  610.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 100)
  611.     Next
  612.     Call set(mantissa.mantissa, digits, 1000000 * (git(mantissa.mantissa, digits) Mod 100))
  613.  
  614. Sub RSHIFT_7 (mantissa As decfloat, digits_in As Long)
  615.     Dim As Long digits
  616.     digits = digits_in
  617.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  618.  
  619.     Dim As Unsigned Long v1, v2
  620.     Dim As Long i
  621.     For i = digits To 1 Step -1
  622.         v1 = git(mantissa.mantissa, i) \ 10000000
  623.         v2 = git(mantissa.mantissa, i - 1) Mod 10000000
  624.         v2 = v2 * 10 + v1
  625.         Call set(mantissa.mantissa, i, v2)
  626.     Next
  627.     Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 10000000)
  628.  
  629. Sub LSHIFT_7 (mantissa As decfloat, digits_in As Long)
  630.     Dim As Long digits
  631.     digits = digits_in
  632.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  633.  
  634.     Dim As Unsigned Long v1, v2
  635.     Dim As Long i
  636.     For i = 0 To digits - 1
  637.         v1 = git(mantissa.mantissa, i) Mod 10
  638.         v2 = git(mantissa.mantissa, i + 1) \ 10
  639.         Call set(mantissa.mantissa, i, v1 * 10000000 + v2)
  640.         Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 10)
  641.     Next
  642.     Call set(mantissa.mantissa, digits, 10000000 * (git(mantissa.mantissa, digits) Mod 10))
  643.  
  644. Sub RSHIFT_8 (mantissa As decfloat, digits_in As Long)
  645.     Dim As Long digits
  646.     digits = digits_in
  647.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  648.     Dim As Long i
  649.     For i = digits To 1 Step -1
  650.         Call set(mantissa.mantissa, i, git(mantissa.mantissa, i - 1))
  651.     Next
  652.     Call set(mantissa.mantissa, 0, 0)
  653.  
  654. Sub LSHIFT_8 (mantissa As decfloat, digits_in As Long)
  655.     Dim As Long digits
  656.     digits = digits_in
  657.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  658.     Dim As Long i
  659.     For i = 0 To digits - 1
  660.         Call set(mantissa.mantissa, i, git(mantissa.mantissa, i + 1))
  661.     Next
  662.     Call set(mantissa.mantissa, digits, 0)
  663.  
  664. Function fpcmp& (x As decfloat, y As decfloat, digits_in As Long)
  665.     Dim As Long digits
  666.     digits = digits_in
  667.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  668.     Dim As Long c, i
  669.     If x.sign < y.sign Then fpcmp = -1: Exit Function
  670.     If x.sign > y.sign Then fpcmp = 1: Exit Function
  671.     If x.sign = y.sign Then
  672.         If x.exponent = y.exponent Then
  673.             For i = 0 To digits
  674.                 c = git(x.mantissa, i) - git(y.mantissa, i)
  675.                 If c <> 0 Then Exit For
  676.             Next
  677.             If c < 0 Then fpcmp = -1: Exit Function
  678.             If c = 0 Then fpcmp = 0: Exit Function
  679.             If c > 0 Then fpcmp = 1: Exit Function
  680.         End If
  681.         If x.exponent < y.exponent Then fpcmp = -1: Exit Function
  682.         If x.exponent > y.exponent Then fpcmp = 1: Exit Function
  683.     End If
  684.     ' if we reach this point it means that the signs are different
  685.     ' and if the sign of x is set meaning that x is negative then x < y
  686.  
  687.  
  688. Sub NORM_FAC1 (fac1 As decfloat, digits_in As Long)
  689.     Dim As Long digits
  690.     digits = digits_in
  691.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  692.     ' normalize the number in fac1
  693.     ' all routines exit through this one.
  694.  
  695.     'see if the mantissa is all zeros.
  696.     'if so, set the exponent and sign equal to 0.
  697.     Dim As Long i, er, f
  698.     er = 0: f = 0
  699.     For i = 0 To digits
  700.         If git(fac1.mantissa, i) > 0 Then f = 1
  701.     Next
  702.     If f = 0 Then
  703.         fac1.exponent = 0
  704.         fac1.sign = 0
  705.         Exit Sub
  706.         'if the highmost Digit in fac1_man is nonzero,
  707.         'shift the mantissa right 1 Digit and
  708.         'increment the exponent
  709.     ElseIf git(fac1.mantissa, 0) > 99999999 Then
  710.         Call RSHIFT_1(fac1, digits)
  711.         fac1.exponent = fac1.exponent + 1
  712.     Else
  713.         'now shift fac1_man 1 to the left until a
  714.         'nonzero digit appears in the next-to-highest
  715.         'Digit of fac1_man.  decrement exponent for
  716.         'each shift.
  717.         While git(fac1.mantissa, 0) = 0
  718.             Call LSHIFT_8(fac1, digits)
  719.             fac1.exponent = fac1.exponent - 8
  720.             If fac1.exponent = 0 Then
  721.                 Print "NORM_FAC1=EXPU_ERR"
  722.                 Exit Sub
  723.             End If
  724.         Wend
  725.         If git(fac1.mantissa, 0) < 10 Then
  726.             Call LSHIFT_7(fac1, digits)
  727.             fac1.exponent = fac1.exponent - 7
  728.         ElseIf git(fac1.mantissa, 0) < 100 Then
  729.             Call LSHIFT_6(fac1, digits)
  730.             fac1.exponent = fac1.exponent - 6
  731.         ElseIf git(fac1.mantissa, 0) < 1000 Then
  732.             Call LSHIFT_5(fac1, digits)
  733.             fac1.exponent = fac1.exponent - 5
  734.         ElseIf git(fac1.mantissa, 0) < 10000 Then
  735.             Call LSHIFT_4(fac1, digits)
  736.             fac1.exponent = fac1.exponent - 4
  737.         ElseIf git(fac1.mantissa, 0) < 100000 Then
  738.             Call LSHIFT_3(fac1, digits)
  739.             fac1.exponent = fac1.exponent - 3
  740.         ElseIf git(fac1.mantissa, 0) < 1000000 Then
  741.             Call LSHIFT_2(fac1, digits)
  742.             fac1.exponent = fac1.exponent - 2
  743.         ElseIf git(fac1.mantissa, 0) < 10000000 Then
  744.             Call LSHIFT_1(fac1, digits)
  745.             fac1.exponent = fac1.exponent - 1
  746.         End If
  747.     End If
  748.     'check for overflow/underflow
  749.     If fac1.exponent < 0 Then
  750.         Print "NORM_FAC1=EXPO_ERR"
  751.     End If
  752.  
  753. Sub fpadd_aux (fac1 As decfloat, fac2 As decfloat, digits_in As Long)
  754.     Dim As Long digits
  755.     digits = digits_in
  756.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  757.     Dim As Unsigned Long v, c, i
  758.     c = 0
  759.     For i = digits To 1 Step -1
  760.         v = git(fac2.mantissa, i) + git(fac1.mantissa, i) + c
  761.         If v > 99999999 Then
  762.             v = v - 100000000
  763.             c = 1
  764.         Else
  765.             c = 0
  766.         End If
  767.         Call set(fac1.mantissa, i, v)
  768.     Next
  769.     v = git(fac1.mantissa, 0) + git(fac2.mantissa, 0) + c
  770.     Call set(fac1.mantissa, 0, v)
  771.  
  772.     Call NORM_FAC1(fac1, digits)
  773.  
  774.  
  775. Sub fpsub_aux (fac1 As decfloat, fac2 As decfloat, digits_in As Long)
  776.     Dim As Long digits
  777.     digits = digits_in
  778.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  779.     Dim As Long v, c, i
  780.     c = 0
  781.     For i = digits To 1 Step -1
  782.         v = git(fac1.mantissa, i) - git(fac2.mantissa, i) - c
  783.         If v < 0 Then
  784.             v = v + 100000000
  785.             c = 1
  786.         Else
  787.             c = 0
  788.         End If
  789.         Call set(fac1.mantissa, i, v)
  790.     Next
  791.     v = git(fac1.mantissa, 0) - git(fac2.mantissa, 0) - c
  792.     Call set(fac1.mantissa, 0, v)
  793.  
  794.     Call NORM_FAC1(fac1, digits)
  795.  
  796. Sub fpadd (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
  797.     Dim As Long digits
  798.     digits = digits_in
  799.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  800.  
  801.     Dim As decfloat fac1, fac2
  802.     Dim As Long i, t, c, xsign, ysign
  803.  
  804.     xsign = x.sign: x.sign = 0
  805.     ysign = y.sign: y.sign = 0
  806.     c = fpcmp(x, y, digits)
  807.  
  808.     x.sign = xsign
  809.     y.sign = ysign
  810.     If c < 0 Then
  811.         fac1 = y
  812.         fac2 = x
  813.     Else
  814.         fac1 = x
  815.         fac2 = y
  816.     End If
  817.     t = fac1.exponent - fac2.exponent
  818.     t = ((fac1.exponent And &H7FFFFFFF) - BIAS - 1) - ((fac2.exponent And &H7FFFFFFF) - BIAS - 1)
  819.  
  820.     If t < (NUM_DIGITS + 8) Then
  821.         'The difference between the two
  822.         'exponents indicate how many times
  823.         'we have to multiply the mantissa
  824.         'of FAC2 by 10 (i.e., shift it right 1 place).
  825.         'If we have to shift more times than
  826.         'we have digits, the result is already in FAC1.
  827.         t = fac1.exponent - fac2.exponent
  828.         If t > 0 And t < (NUM_DIGITS + 8) Then 'shift
  829.  
  830.             i = t \ 8
  831.             While i > 0
  832.                 Call RSHIFT_8(fac2, digits)
  833.                 t = t - 8
  834.                 i = i - 1
  835.             Wend
  836.             If t = 7 Then
  837.                 Call RSHIFT_7(fac2, digits)
  838.             ElseIf t = 6 Then
  839.                 Call RSHIFT_6(fac2, digits)
  840.             ElseIf t = 5 Then
  841.                 Call RSHIFT_5(fac2, digits)
  842.             ElseIf t = 4 Then
  843.                 Call RSHIFT_4(fac2, digits)
  844.             ElseIf t = 3 Then
  845.                 Call RSHIFT_3(fac2, digits)
  846.             ElseIf t = 2 Then
  847.                 Call RSHIFT_2(fac2, digits)
  848.             ElseIf t = 1 Then
  849.                 Call RSHIFT_1(fac2, digits)
  850.             End If
  851.         End If
  852.         'See if the signs of the two numbers
  853.         'are the same.  If so, add; if not, subtract.
  854.         If fac1.sign = fac2.sign Then 'add
  855.             Call fpadd_aux(fac1, fac2, digits)
  856.         Else
  857.             Call fpsub_aux(fac1, fac2, digits)
  858.         End If
  859.     End If
  860.     result = fac1
  861.  
  862. Sub fpsub (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
  863.     Dim As Long digits
  864.     digits = digits_in
  865.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  866.     Dim As decfloat fac1, fac2
  867.     fac1 = x
  868.     fac2 = y
  869.     fac2.sign = fac2.sign Xor &H8000
  870.     Call fpadd(fac1, fac1, fac2, digits)
  871.     result = fac1
  872.  
  873. Sub fpmul (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
  874.     Dim As Long digits
  875.     digits = digits_in
  876.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  877.     Dim As decfloat fac1, fac2
  878.     Dim As Long i, j, ex, er, den, num
  879.     Dim As Integer64 digit, carry
  880.     Dim As Unsigned Integer64 fac3(0 To digits)
  881.  
  882.     fac1 = x
  883.     fac2 = y
  884.     'check exponents.  if either is zero,
  885.     'the result is zero
  886.     If fac1.exponent = 0 Or fac2.exponent = 0 Then 'result is zero...clear fac1.
  887.         fac1.sign = 0
  888.         fac1.exponent = 0
  889.         For i = 0 To digits
  890.             Call set(fac1.mantissa, i, 0)
  891.         Next
  892.         'NORM_FAC1(fac1)
  893.         result = fac1: Exit Sub
  894.     Else
  895.  
  896.         If ex < 0 Then
  897.             er = EXPO_ERR
  898.             result = fac1: Exit Sub
  899.         End If
  900.  
  901.         'clear fac3 mantissa
  902.         For i = 0 To digits
  903.             fac3(i) = 0
  904.         Next
  905.  
  906.         den = digits
  907.         While git(fac2.mantissa, den) = 0
  908.             den = den - 1
  909.         Wend
  910.         num = digits
  911.         While git(fac1.mantissa, num) = 0
  912.             num = num - 1
  913.         Wend
  914.  
  915.         If num < den Then
  916.             Swap fac1, fac2
  917.             'fac1=y
  918.             'fac2=x
  919.             Swap den, num
  920.         End If
  921.  
  922.         For j = den To 0 Step -1
  923.             carry = 0
  924.             digit = git(fac2.mantissa, j)
  925.             For i = num To 0 Step -1
  926.                 fac3(i) = fac3(i) + digit * git(fac1.mantissa, i)
  927.             Next
  928.             For i = num To 0 Step -1
  929.                 fac3(i) = fac3(i) + carry
  930.                 carry = fac3(i) \ 100000000
  931.                 fac3(i) = (fac3(i) Mod 100000000)
  932.             Next
  933.  
  934.             For i = digits To 1 Step -1
  935.                 fac3(i) = fac3(i - 1)
  936.             Next
  937.             fac3(0) = carry
  938.         Next
  939.  
  940.         For i = 0 To digits
  941.             Call set(fac1.mantissa, i, fac3(i))
  942.         Next
  943.     End If
  944.     'now determine exponent of result.
  945.     'as you do...watch for overflow.
  946.     ex = fac2.exponent - BIAS + fac1.exponent
  947.     fac1.exponent = ex
  948.     'determine the sign of the product
  949.     fac1.sign = fac1.sign Xor fac2.sign
  950.     Call NORM_FAC1(fac1, digits)
  951.     result = fac1
  952.  
  953. Sub fpmul_si (result As decfloat, x As decfloat, y As Integer64, digits_in As Long)
  954.     Dim As Long digits
  955.     digits = digits_in
  956.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  957.     Dim As decfloat fac1, fac2
  958.     Dim As Long count, ex, er, i
  959.     Dim As Integer64 carry, digit, prod, value
  960.     fac1 = x
  961.     digit = Abs(y)
  962.     If digit > 99999999 Then
  963.         Call si2fp(fac2, y, digits)
  964.         Call fpmul(fac1, fac1, fac2, digits)
  965.         result = fac1: Exit Sub
  966.     End If
  967.     'check exponents.  if either is zero,
  968.     'the result is zero
  969.     If fac1.exponent = 0 Or y = 0 Then 'result is zero...clear fac1.
  970.         fac1.sign = 0
  971.         fac1.exponent = 0
  972.         For count = 0 To digits
  973.             Call set(fac1.mantissa, count, 0)
  974.         Next
  975.         Call NORM_FAC1(fac1, digits)
  976.         result = fac1: Exit Sub
  977.     Else
  978.         If digit = 1 Then
  979.             If y < 0 Then
  980.                 fac1.sign = fac1.sign Xor &H8000
  981.             End If
  982.             result = fac1: Exit Sub
  983.         End If
  984.         'now determine exponent of result.
  985.         'as you do...watch for overflow.
  986.  
  987.         If ex < 0 Then
  988.             er = EXPO_ERR
  989.             result = fac1: Exit Sub
  990.         End If
  991.  
  992.         carry = 0
  993.  
  994.         For i = digits To 0 Step -1
  995.             prod = digit * git(fac1.mantissa, i) + carry
  996.             value = (prod Mod 100000000)
  997.             Call set(fac1.mantissa, i, value)
  998.             carry = prod \ 100000000
  999.         Next
  1000.  
  1001.         If carry < 10 Then
  1002.             Call RSHIFT_1(fac1, digits)
  1003.             fac1.exponent = fac1.exponent + 1
  1004.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000000)
  1005.         ElseIf carry < 100 Then
  1006.             Call RSHIFT_2(fac1, digits)
  1007.             fac1.exponent = fac1.exponent + 2
  1008.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000000)
  1009.         ElseIf carry < 1000 Then
  1010.             Call RSHIFT_3(fac1, digits)
  1011.             fac1.exponent = fac1.exponent + 3
  1012.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100000)
  1013.         ElseIf carry < 10000 Then
  1014.             Call RSHIFT_4(fac1, digits)
  1015.             fac1.exponent = fac1.exponent + 4
  1016.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000)
  1017.         ElseIf carry < 100000 Then
  1018.             Call RSHIFT_5(fac1, digits)
  1019.             fac1.exponent = fac1.exponent + 5
  1020.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000)
  1021.         ElseIf carry < 1000000 Then
  1022.             Call RSHIFT_6(fac1, digits)
  1023.             fac1.exponent = fac1.exponent + 6
  1024.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100)
  1025.         ElseIf carry < 10000000 Then
  1026.             Call RSHIFT_7(fac1, digits)
  1027.             fac1.exponent = fac1.exponent + 7
  1028.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10)
  1029.         ElseIf carry < 100000000 Then
  1030.             Call RSHIFT_8(fac1, digits)
  1031.             fac1.exponent = fac1.exponent + 8
  1032.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry)
  1033.         End If
  1034.  
  1035.     End If
  1036.  
  1037.     Call NORM_FAC1(fac1, digits)
  1038.  
  1039.     If y < 0 Then
  1040.         fac1.sign = fac1.sign Xor &H8000
  1041.     End If
  1042.     result = fac1
  1043.  
  1044. Sub fpmul_ll (result As decfloat, x As decfloat, y As Integer64, digits_in As Long)
  1045.     Dim As Long digits
  1046.     digits = digits_in
  1047.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1048.     Dim As decfloat fac1, fac2
  1049.     Dim As Long count, ex, er, i
  1050.     Dim As Integer64 carry, digit, prod, value, n0, n1
  1051.     fac1 = x
  1052.     digit = Abs(y)
  1053.     If digit > 99999999 And digit < 10000000000000000 Then
  1054.         n0 = digit \ 100000000
  1055.         n1 = digit Mod 100000000
  1056.         Call fpmul_si(fac2, fac1, n1, digits)
  1057.         fac1.exponent = fac1.exponent + 8
  1058.         Call fpmul_si(fac1, fac1, n0, digits)
  1059.         Call fpadd(fac1, fac1, fac2, digits)
  1060.         If y < 0 Then fac1.sign = fac1.sign Xor &H8000
  1061.         result = fac1: Exit Sub
  1062.     End If
  1063.     If digit > 9999999999999999 Then
  1064.         Call str2fp(fac2, Str$(y))
  1065.         Call fpmul(fac1, fac1, fac2, digits)
  1066.         result = fac1: Exit Sub
  1067.     End If
  1068.     Call si2fp(fac2, y, digits)
  1069.  
  1070.     'check exponents.  if either is zero,
  1071.     'the result is zero
  1072.     If fac1.exponent = 0 Or y = 0 Then 'result is zero...clear fac1.
  1073.         fac1.sign = 0
  1074.         fac1.exponent = 0
  1075.         For count = 0 To digits
  1076.             Call set(fac1.mantissa, count, 0)
  1077.         Next
  1078.         Call NORM_FAC1(fac1, digits)
  1079.         result = fac1: Exit Sub
  1080.     Else
  1081.         If digit = 1 Then
  1082.             If y < 0 Then
  1083.                 fac1.sign = fac1.sign Xor &H8000
  1084.             End If
  1085.             result = fac1: Exit Sub
  1086.         End If
  1087.         'now determine exponent of result.
  1088.         'as you do...watch for overflow.
  1089.  
  1090.         If ex < 0 Then
  1091.             er = EXPO_ERR
  1092.             result = fac1: Exit Sub
  1093.         End If
  1094.  
  1095.         carry = 0
  1096.  
  1097.         For i = digits To 0 Step -1
  1098.             prod = digit * git(fac1.mantissa, i) + carry
  1099.             value = (prod Mod 100000000)
  1100.             Call set(fac1.mantissa, i, value)
  1101.             carry = prod \ 100000000
  1102.         Next
  1103.  
  1104.         If carry < 10 Then
  1105.             Call RSHIFT_1(fac1, digits)
  1106.             fac1.exponent = fac1.exponent + 1
  1107.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000000)
  1108.         ElseIf carry < 100 Then
  1109.             Call RSHIFT_2(fac1, digits)
  1110.             fac1.exponent = fac1.exponent + 2
  1111.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000000)
  1112.         ElseIf carry < 1000 Then
  1113.             Call RSHIFT_3(fac1, digits)
  1114.             fac1.exponent = fac1.exponent + 3
  1115.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100000)
  1116.         ElseIf carry < 10000 Then
  1117.             Call RSHIFT_4(fac1, digits)
  1118.             fac1.exponent = fac1.exponent + 4
  1119.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000)
  1120.         ElseIf carry < 100000 Then
  1121.             Call RSHIFT_5(fac1, digits)
  1122.             fac1.exponent = fac1.exponent + 5
  1123.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000)
  1124.         ElseIf carry < 1000000 Then
  1125.             Call RSHIFT_6(fac1, digits)
  1126.             fac1.exponent = fac1.exponent + 6
  1127.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100)
  1128.         ElseIf carry < 10000000 Then
  1129.             Call RSHIFT_7(fac1, digits)
  1130.             fac1.exponent = fac1.exponent + 7
  1131.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10)
  1132.         ElseIf carry < 100000000 Then
  1133.             Call RSHIFT_8(fac1, digits)
  1134.             fac1.exponent = fac1.exponent + 8
  1135.             Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry)
  1136.         End If
  1137.  
  1138.     End If
  1139.  
  1140.     Call NORM_FAC1(fac1, digits)
  1141.  
  1142.     If y < 0 Then
  1143.         fac1.sign = fac1.sign Xor &H8000
  1144.     End If
  1145.     result = fac1
  1146.  
  1147. Sub fpinv (result As decfloat, m As decfloat, digits_in As Long)
  1148.     Dim As Long digits
  1149.     digits = digits_in
  1150.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1151.     Dim As Double x
  1152.     Dim As Long k, l, ex
  1153.     Dim As Long prec
  1154.     Dim As decfloat r, r2, one, n
  1155.     n = m
  1156.     l = Log((NUM_DIGITS + 8) * 0.0625) * 1.5
  1157.     Dim As String v, ts
  1158.     If n.exponent > 0 Then
  1159.         ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
  1160.     Else
  1161.         ex = 0
  1162.     End If
  1163.  
  1164.     If n.sign Then v = "-" Else v = " "
  1165.     ts = Str$(git(n.mantissa, 0))
  1166.     If Len(ts) < 8 Then
  1167.         ts = ts + String$(8 - Len(ts), "0")
  1168.     End If
  1169.     v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
  1170.     ts = Str$(git(n.mantissa, 1))
  1171.     If Len(ts) < 8 Then
  1172.         ts = String$(8 - Len(ts), "0") + ts
  1173.     End If
  1174.     v = v + ts
  1175.     x = Val(v)
  1176.     If x = 0 Then Print "Div 0": result = r: Exit Sub
  1177.     If x = 1 And ex = 0 Then
  1178.         Call str2fp(r, "1")
  1179.         result = r: Exit Sub
  1180.     ElseIf x = 1 Then
  1181.         x = 10
  1182.         ex = ex - 1
  1183.     End If
  1184.     ex = (-1) - ex
  1185.     x = 1 / x
  1186.     Call str2fp(r, Str$(x))
  1187.     r.exponent = ex + BIAS + 1
  1188.     Call set(one.mantissa, 0, 10000000)
  1189.     one.exponent = BIAS + 1
  1190.     r2 = r
  1191.     prec = 3
  1192.     For k = 1 To l
  1193.         prec = 2 * prec - 1
  1194.         Call fpmul(r2, n, r, prec)
  1195.         Call fpsub(r2, one, r2, prec)
  1196.         Call fpmul(r2, r, r2, prec)
  1197.         Call fpadd(r, r, r2, prec)
  1198.     Next
  1199.     result = r
  1200.  
  1201. Function min& (a As Long, b As Long)
  1202.     If a < b Then min& = a Else min& = b
  1203.  
  1204. Function RealW# (w() As Double, j As Long)
  1205.     Dim wx As Double
  1206.     wx = ((w(j - 1) * 10000 + w(j)) * 10000 + w(j + 1)) * 10000
  1207.     If UBound(w) >= (j + 2) Then wx = wx + w(j + 2)
  1208.     RealW# = wx
  1209.  
  1210. Sub subtract (w() As Double, q As Long, d() As Double, ka As Long, kb As Long)
  1211.     Dim As Long j
  1212.     For j = ka To kb
  1213.         w(j) = w(j) - q * d(j - ka + 2)
  1214.     Next
  1215.  
  1216. Sub normalize (w() As Double, ka As Long, q As Long)
  1217.     w(ka) = w(ka) + w(ka - 1) * 10000
  1218.     w(ka - 1) = q
  1219.  
  1220. Sub finalnorm (w() As Double, kb As Long)
  1221.     Dim As Long carry, j
  1222.     For j = kb To 3 Step -1
  1223.         If w(j) < 0 Then
  1224.             carry = ((-w(j) - 1) \ 10000) + 1
  1225.         Else
  1226.             If w(j) >= 10000 Then
  1227.                 carry = -(w(j) \ 10000)
  1228.             Else
  1229.                 carry = 0
  1230.             End If
  1231.         End If
  1232.         w(j) = w(j) + carry * 10000
  1233.         w(j - 1) = w(j - 1) - carry
  1234.     Next
  1235.  
  1236. Sub fpdiv (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
  1237.     Dim As Long digits
  1238.     digits = digits_in
  1239.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1240.     Dim As decfloat fac1, fac2
  1241.     Dim As Long i, er, is_power_of_ten
  1242.  
  1243.     fac1 = x
  1244.     fac2 = y
  1245.  
  1246.     If fac2.exponent = 0 Then ' if fac2 = 0, return
  1247.         ' a divide-by-zero error and
  1248.         ' bail out.
  1249.         For i = 0 To digits
  1250.             Call set(fac1.mantissa, i, 99999999)
  1251.         Next
  1252.         fac1.exponent = 99999 + BIAS + 1
  1253.         er = DIVZ_ERR
  1254.         result = fac1
  1255.         Exit Sub
  1256.     ElseIf fac1.exponent = 0 Then 'fact1=0, just return
  1257.         er = 0
  1258.         result = fac1
  1259.         Exit Sub
  1260.     Else
  1261.         'check to see if fac2 is a power of ten
  1262.         is_power_of_ten = 0
  1263.         If git(fac2.mantissa, 0) = 10000000 Then
  1264.             is_power_of_ten = 1
  1265.             For i = 1 To digits
  1266.                 If git(fac2.mantissa, i) <> 0 Then
  1267.                     is_power_of_ten = 0
  1268.                     Exit For
  1269.                 End If
  1270.             Next
  1271.         End If
  1272.         'if fac2 is a power of ten then all we need to do is to adjust the sign and exponent and we are finished
  1273.         If is_power_of_ten = 1 Then
  1274.             fac1.sign = fac1.sign Xor fac2.sign
  1275.             fac1.exponent = fac1.exponent - fac2.exponent + BIAS + 1
  1276.             result = fac1
  1277.             Exit Sub
  1278.         End If
  1279.  
  1280.         Dim As Double result(1 To 2 * digits + 3), n(1 To 2 * digits + 3), d(1 To 2 * digits + 3)
  1281.         Const b = 10000
  1282.         Dim As Long j, last, laststep, q, t
  1283.         Dim As Long stp
  1284.         Dim As Double xd, xn, rund
  1285.         Dim As Double w(1 To UBound(n) + 4)
  1286.  
  1287.         For j = 0 To digits
  1288.             n(2 * j + 2) = git(fac1.mantissa, j) \ 10000
  1289.             n(2 * j + 3) = git(fac1.mantissa, j) Mod 10000
  1290.             d(2 * j + 2) = git(fac2.mantissa, j) \ 10000
  1291.             d(2 * j + 3) = git(fac2.mantissa, j) Mod 10000
  1292.         Next
  1293.         n(1) = (fac1.exponent And &H7FFFFFFF) - BIAS - 1
  1294.         d(1) = (fac2.exponent And &H7FFFFFFF) - BIAS - 1
  1295.         For j = UBound(n) To UBound(w)
  1296.             w(j) = 0
  1297.         Next
  1298.         t = UBound(n) - 1
  1299.         w(1) = n(1) - d(1) + 1
  1300.         w(2) = 0
  1301.         For j = 2 To UBound(n)
  1302.             w(j + 1) = n(j)
  1303.         Next
  1304.         xd = (d(2) * b + d(3)) * b + d(4) + d(5) / b
  1305.         laststep = t + 2
  1306.         For stp = 1 To laststep
  1307.             xn = RealW(w(), (stp + 2))
  1308.             q = Int(xn / xd)
  1309.             last = min(stp + t + 1, UBound(w))
  1310.             Call subtract(w(), q, d(), (stp + 2), last)
  1311.             Call normalize(w(), (stp + 2), q)
  1312.         Next
  1313.         Call finalnorm(w(), (laststep + 1))
  1314.         If w(2) <> 0 Then laststep = laststep - 1
  1315.         rund = w(laststep + 1) / b
  1316.         If rund >= 0.5 Then w(laststep) = w(laststep) + 1
  1317.         If w(2) = 0 Then
  1318.             For j = 1 To t + 1
  1319.                 result(j) = w(j + 1)
  1320.             Next
  1321.         Else
  1322.             For j = 1 To t + 1
  1323.                 result(j) = w(j)
  1324.             Next
  1325.         End If
  1326.         If w(2) = 0 Then result(1) = w(1) - 1 Else result(1) = w(1)
  1327.  
  1328.         For j = 0 To digits
  1329.             Call set(fac1.mantissa, j, result(2 * j + 2) * 10000 + result(2 * j + 3))
  1330.         Next
  1331.         Call NORM_FAC1(fac1, digits)
  1332.         fac1.exponent = (result(1) + BIAS)
  1333.     End If
  1334.     fac1.sign = fac1.sign Xor fac2.sign
  1335.     result = fac1
  1336.  
  1337. ' sqrt(num)
  1338. Sub fpsqr (result As decfloat, num As decfloat, digits_in As Long)
  1339.     Dim As Long digits
  1340.     digits = digits_in
  1341.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1342.     Dim As decfloat r, r2, tmp, n, half
  1343.     Dim As Long ex, k, l, prec
  1344.     Dim As String ts, v
  1345.     Dim As Double x
  1346.     l = Log((NUM_DIGITS + 8) * 0.0625) * 1.5
  1347.     'l=estimated number of iterations needed
  1348.     'first estimate is accurate to about 16 digits
  1349.     'l is approximatly = to log2((NUM_DIGITS+9)/16)
  1350.     'NUM_DIGITS+9 because decfloat has an extra 9 guard digits
  1351.     n = num
  1352.     Call si2fp(tmp, 0, digits)
  1353.     If fpcmp(n, tmp, digits) = 0 Then
  1354.         Call si2fp(r, 0, digits)
  1355.         result = r
  1356.         Exit Sub
  1357.     End If
  1358.     Call si2fp(tmp, 1, digits)
  1359.     If fpcmp(n, tmp, digits) = 0 Then
  1360.         Call si2fp(r, 1, digits)
  1361.         result = r
  1362.         Exit Sub
  1363.     End If
  1364.     Call si2fp(tmp, 0, digits)
  1365.     If fpcmp(n, tmp, digits) < 0 Then
  1366.         Call si2fp(r, 0, digits)
  1367.         result = r
  1368.         Exit Sub
  1369.     End If
  1370.     '=====================================================================
  1371.     'hack to bypass the limitation of double exponent range
  1372.     'in case the number is larger than what a double can handle
  1373.     'for example, if the number is 2e500
  1374.     'we separate the exponent and mantissa in this case 2
  1375.     'if the exponent is odd then multiply the mantissa by 10
  1376.     'take the square root and assign it to decfloat
  1377.     'divide the exponent in half for square root
  1378.     'in this case 1.414213562373095e250
  1379.     If n.exponent > 0 Then
  1380.         ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
  1381.     Else
  1382.         ex = 0
  1383.     End If
  1384.     ts = Trim$(Str$(git(n.mantissa, 0)))
  1385.     If Len(ts) < 8 Then
  1386.         ts = ts + String$(8 - Len(ts), "0")
  1387.     End If
  1388.     v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
  1389.     ts = Trim$(Str$(git(n.mantissa, 1)))
  1390.     If Len(ts) < 8 Then
  1391.         ts = String$(8 - Len(ts), "0") + ts
  1392.     End If
  1393.     v = v + ts
  1394.     x = Val(v)
  1395.     If x = 0 Then Print "Div 0": result = r: Exit Sub
  1396.     If x = 1 And ex = 0 Then
  1397.         Call si2fp(r, 1, digits)
  1398.         result = r
  1399.         Exit Sub
  1400.     End If
  1401.     If Abs(ex) And 1 Then
  1402.         x = x * 10
  1403.         ex = ex - 1
  1404.     End If
  1405.     x = Sqr(x) 'approximation
  1406.     v = Trim$(Str$(x))
  1407.     k = InStr(v, ".")
  1408.     Call str2fp(r, v)
  1409.     r.exponent = ex \ 2 + BIAS + 1
  1410.     If Len(v) > 1 And k = 0 Then r.exponent = r.exponent + 1
  1411.     For k = 1 To digits
  1412.         Call set(half.mantissa, k, 0)
  1413.     Next
  1414.     Call set(half.mantissa, 0, 50000000)
  1415.     half.exponent = BIAS
  1416.     half.sign = 0
  1417.     '=====================================================================
  1418.     'Newton-Raphson method
  1419.     prec = 3
  1420.     For k = 1 To l + 1
  1421.         prec = 2 * prec - 1
  1422.         Call fpdiv(tmp, n, r, prec)
  1423.         Call fpadd(r2, r, tmp, prec)
  1424.         Call fpmul(r, r2, half, prec)
  1425.     Next
  1426.     result = r
  1427.  
  1428. Sub fpdiv_si (result As decfloat, num As decfloat, den As Long, digits_in As Long)
  1429.     Dim As Long digits
  1430.     digits = digits_in
  1431.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1432.     Dim As decfloat fac1
  1433.     Dim As Unsigned Integer64 carry, remder
  1434.     Dim As Integer64 i, divisor
  1435.     Dim As Integer64 quotient
  1436.     remder = 0
  1437.     divisor = Abs(den)
  1438.     fac1 = num
  1439.     If divisor = 0 Then
  1440.         Print "error: divisor = 0"
  1441.         result = fac1: Exit Sub
  1442.     End If
  1443.     If divisor > 99999999 Then
  1444.         Print "error: divisor too large"
  1445.         result = fac1: Exit Sub
  1446.     End If
  1447.  
  1448.     For i = 0 To digits
  1449.         quotient = git(fac1.mantissa, i) + remder * 100000000
  1450.         remder = quotient Mod divisor
  1451.         Call set(fac1.mantissa, i, quotient \ divisor)
  1452.     Next
  1453.     quotient = remder * 100000000
  1454.     quotient = quotient \ divisor
  1455.     carry = git(fac1.mantissa, 0)
  1456.  
  1457.     If carry = 0 Then
  1458.         Call LSHIFT_8(fac1, digits)
  1459.         fac1.exponent = fac1.exponent - 8
  1460.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient)
  1461.     ElseIf carry < 10 Then
  1462.         Call LSHIFT_7(fac1, digits)
  1463.         fac1.exponent = fac1.exponent - 7
  1464.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 10)
  1465.     ElseIf carry < 100 Then
  1466.         Call LSHIFT_6(fac1, digits)
  1467.         fac1.exponent = fac1.exponent - 6
  1468.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 100)
  1469.     ElseIf carry < 1000 Then
  1470.         Call LSHIFT_5(fac1, digits)
  1471.         fac1.exponent = fac1.exponent - 5
  1472.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 1000)
  1473.     ElseIf carry < 10000 Then
  1474.         Call LSHIFT_4(fac1, digits)
  1475.         fac1.exponent = fac1.exponent - 4
  1476.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 10000)
  1477.     ElseIf carry < 100000 Then
  1478.         Call LSHIFT_3(fac1, digits)
  1479.         fac1.exponent = fac1.exponent - 3
  1480.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 100000)
  1481.     ElseIf carry < 1000000 Then
  1482.         Call LSHIFT_2(fac1, digits)
  1483.         fac1.exponent = fac1.exponent - 2
  1484.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 1000000)
  1485.     ElseIf carry < 10000000 Then
  1486.         Call LSHIFT_1(fac1, digits)
  1487.         fac1.exponent = fac1.exponent - 1
  1488.         Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 10000000)
  1489.     End If
  1490.  
  1491.     'NORM_FAC1(fac1)
  1492.     If den < 0 Then
  1493.         fac1.sign = fac1.sign Xor &H8000
  1494.     End If
  1495.     result = fac1
  1496.  
  1497. 'fractional part of num
  1498. Sub fpfrac (result As decfloat, num As decfloat, digits_in As Long)
  1499.     Dim As Long digits
  1500.     digits = digits_in
  1501.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1502.     Dim As decfloat n
  1503.     Call fpfix(n, num)
  1504.     Call fpsub(n, num, n, digits)
  1505.     result = n
  1506.  
  1507. 'returns the positive of n
  1508. Sub fpabs (result As decfloat, n As decfloat)
  1509.     Dim As decfloat x
  1510.     x = n
  1511.     x.sign = 0
  1512.     result = x
  1513.  
  1514. 'changes the sign of n, if n is positive then n will be negative & vice versa
  1515. Sub fpneg (result As decfloat, n As decfloat)
  1516.     Dim As decfloat x
  1517.     x = n
  1518.     x.sign = x.sign Xor &H8000
  1519.     result = x
  1520.  
  1521. 'returns the negative of n regardless of the sign of n
  1522. Sub fpnegative (result As decfloat, n As decfloat)
  1523.     Dim As decfloat x
  1524.     x = n
  1525.     x.sign = &H8000
  1526.     result = x
  1527.  
  1528. Sub fpfmod (quotient As decfloat, f_mod As decfloat, num As decfloat, denom As decfloat, digits As Long)
  1529.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1530.     Dim As decfloat q, fm 'make copy in case the destination and source are the same
  1531.     Call fpdiv(fm, num, denom, digits): Call fpfix(q, fm)
  1532.     Call fpsub(fm, fm, q, digits): Call fpmul(fm, fm, denom, digits)
  1533.     quotient = q
  1534.     f_mod = fm
  1535.  
  1536. Sub fpeps (result As decfloat, digits As Long)
  1537.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1538.     Dim As decfloat ep
  1539.     Call si2fp(ep, 1, digits)
  1540.     ep.exponent = (-(NUM_DIGITS) + BIAS + 1)
  1541.     result = ep
  1542.  
  1543. Sub fpipow (result As decfloat, x As decfloat, e As Integer64, digits_in As Long)
  1544.     Dim As Long digits
  1545.     digits = digits_in
  1546.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1547.     'take x to an Long power
  1548.     Dim As decfloat y
  1549.     Dim As decfloat z
  1550.     Dim As Integer64 n, c
  1551.     Dim As Long i
  1552.     c = 0
  1553.     y = x
  1554.     n = Abs(e)
  1555.     z.sign = 0
  1556.     z.exponent = (BIAS + 1)
  1557.     Call set(z.mantissa, 0, 10000000)
  1558.     For i = 1 To NUM_DWORDS
  1559.         Call set(z.mantissa, i, 0)
  1560.     Next
  1561.     While n > 0
  1562.         While (n And 1) = 0
  1563.             n = n \ 2
  1564.             Call fpmul(y, y, y, digits)
  1565.             c = c + 1
  1566.         Wend
  1567.         n = n - 1
  1568.         Call fpmul(z, y, z, digits)
  1569.         c = c + 1
  1570.     Wend
  1571.     If e < 0 Then
  1572.         Call fpinv(z, z, digits)
  1573.     End If
  1574.     result = z
  1575.  
  1576. Sub fpfactorial (result As decfloat, n As Long, digits_in As Long)
  1577.     Dim As Long digits
  1578.     digits = digits_in
  1579.     Dim As Long i
  1580.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1581.     Dim As decfloat f
  1582.     If n < 0 Then Print "inf": result = f: Exit Sub
  1583.     If n = 0 Or n = 1 Then
  1584.         Call si2fp(f, 1, digits)
  1585.         result = f: Exit Sub
  1586.     End If
  1587.     Call si2fp(f, 2, digits)
  1588.     If n = 2 Then result = f: Exit Sub
  1589.     For i = 3 To n
  1590.         Call fpmul_si(f, f, i, digits)
  1591.     Next
  1592.     result = f
  1593.  
  1594. Sub fplogTaylor (result As decfloat, x As decfloat, digits_in As Long)
  1595.     Dim As Long digits
  1596.     digits = digits_in
  1597.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1598.     'taylor series
  1599.     '====================Log Guard==================
  1600.     Dim As decfloat g, zero
  1601.     Dim As Long i
  1602.     Call fpabs(g, x)
  1603.     zero.sign = 0
  1604.     zero.exponent = 0
  1605.     For i = 0 To NUM_DWORDS
  1606.         Call set(zero.mantissa, i, 0)
  1607.     Next
  1608.     If fpcmp(g, x, digits) <> 0 Then result = zero: Exit Sub
  1609.     If fpcmp(x, zero, digits) = 0 Then result = zero: Exit Sub
  1610.     '=============================================
  1611.     Dim As Long invflag
  1612.     Dim As decfloat XX, Term, Accum, x9, tmp, tmp2
  1613.     Dim As decfloat T, B, one, Q, two
  1614.  
  1615.     one.sign = 0
  1616.     one.exponent = (BIAS + 1)
  1617.     Call set(one.mantissa, 0, 10000000)
  1618.     two.sign = 0
  1619.     two.exponent = (BIAS + 1)
  1620.     Call set(two.mantissa, 0, 20000000)
  1621.     For i = 1 To NUM_DWORDS
  1622.         Call set(one.mantissa, i, 0)
  1623.         Call set(two.mantissa, i, 0)
  1624.     Next
  1625.     x9 = x
  1626.     If fpcmp(x, one, digits) < 0 Then
  1627.         invflag = 1
  1628.         Call fpdiv(x9, one, x9, digits)
  1629.     End If
  1630.     Call fpsub(T, x9, one, digits)
  1631.     Call fpadd(B, x9, one, digits)
  1632.     Call fpdiv(Accum, T, B, digits)
  1633.     Call fpdiv(Q, T, B, digits)
  1634.     tmp = Q
  1635.     Call fpmul(XX, Q, Q, digits)
  1636.     Dim As Long c
  1637.     c = 1
  1638.     Do
  1639.         c = c + 2
  1640.         tmp2 = tmp
  1641.         Call fpmul(Q, Q, XX, digits)
  1642.         Call fpdiv_si(Term, Q, c, digits)
  1643.         Call fpadd(Accum, tmp, Term, digits)
  1644.         Swap tmp, Accum
  1645.     Loop Until fpcmp(tmp, tmp2, digits) = 0
  1646.     Call fpmul_si(Accum, Accum, 2, digits)
  1647.     If invflag Then
  1648.         Call fpneg(Accum, Accum)
  1649.         result = Accum: Exit Sub
  1650.     End If
  1651.     result = Accum
  1652.  
  1653. Sub fplog (result As decfloat, x As decfloat, digits_in As Long)
  1654.     Dim As Long digits
  1655.     digits = digits_in
  1656.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1657.     '====================Log Guard==================
  1658.     Dim As decfloat g, one, zero
  1659.     Dim As Long i, factor
  1660.     zero.sign = 0
  1661.     zero.exponent = 0
  1662.     For i = 0 To NUM_DWORDS
  1663.         Call set(zero.mantissa, i, 0)
  1664.     Next
  1665.     Call si2fp(one, 1, digits)
  1666.     Call fpabs(g, x)
  1667.     If fpcmp(g, x, digits) <> 0 Then result = zero: Exit Sub
  1668.     If fpcmp(x, zero, digits) = 0 Then result = zero: Exit Sub
  1669.     If fpcmp(x, one, digits) = 0 Then result = zero: Exit Sub
  1670.     '=============================================
  1671.     Dim As decfloat approx, ans, logx
  1672.     approx = x
  1673.     factor = 4096
  1674.     Call fpsqr(approx, approx, digits)
  1675.     Call fpsqr(approx, approx, digits)
  1676.     Call fpsqr(approx, approx, digits)
  1677.     Call fpsqr(approx, approx, digits)
  1678.     Call fpsqr(approx, approx, digits)
  1679.     Call fpsqr(approx, approx, digits)
  1680.     Call fpsqr(approx, approx, digits)
  1681.     Call fpsqr(approx, approx, digits)
  1682.     Call fpsqr(approx, approx, digits)
  1683.     Call fpsqr(approx, approx, digits)
  1684.     Call fpsqr(approx, approx, digits)
  1685.     Call fpsqr(approx, approx, digits)
  1686.     Call fplogTaylor(logx, approx, digits)
  1687.     Call fpmul_si(ans, logx, factor, digits)
  1688.     result = ans
  1689.  
  1690. Sub fpexp (result As decfloat, x As decfloat, digits_in As Long)
  1691.     Dim As Long digits
  1692.     digits = digits_in
  1693.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1694.     'taylor series
  1695.     Dim As decfloat fac, x9, temp, accum, p, term
  1696.     Dim As Long i, c
  1697.     Call si2fp(temp, 0, digits)
  1698.  
  1699.     fac.sign = 0
  1700.     fac.exponent = (BIAS + 1)
  1701.     Call set(fac.mantissa, 0, 10000000)
  1702.     For i = 1 To NUM_DWORDS
  1703.         Call set(fac.mantissa, i, 0)
  1704.     Next
  1705.     If fpcmp(x, temp, digits) = 0 Then result = fac: Exit Sub
  1706.     c = 1
  1707.     Call fpdiv_si(x9, x, 8192, digits) 'fpdiv_si(x, 67108864) '
  1708.     p = x9
  1709.     Call fpadd(accum, fac, x9, digits) '1 + x
  1710.  
  1711.     Do
  1712.         c = c + 1
  1713.         temp = accum
  1714.         Call fpdiv_si(fac, fac, c, digits)
  1715.         Call fpmul(p, p, x9, digits)
  1716.         Call fpmul(term, p, fac, digits)
  1717.         Call fpadd(accum, temp, term, digits)
  1718.     Loop Until fpcmp(accum, temp, digits) = 0
  1719.     For i = 1 To 13
  1720.         Call fpmul(accum, accum, accum, digits)
  1721.     Next
  1722.     result = accum
  1723.  
  1724. Sub fpexp_cf (result As decfloat, x As decfloat, n As Long, digits_in As Long)
  1725.     Dim As Long digits
  1726.     digits = digits_in
  1727.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1728.  
  1729.     '                       x
  1730.     '    cf =   ------------------------------
  1731.     '                         x^2
  1732.     '           2 + -------------------------
  1733.     '                           x^2
  1734.     '              6 + ----------------------
  1735.     '                             x^2
  1736.     '                 10 + ------------------
  1737.     '                               x^2
  1738.     '                     14 + --------------
  1739.     '                                 x^2
  1740.     '                          18 + ---------
  1741.     '                                   x^2
  1742.     '                              22 + -----
  1743.     '                                   26 + ...
  1744.     '           (1 + cf)
  1745.     ' exp(x) = ----------
  1746.     '           (1 - cf)
  1747.  
  1748.     Dim i As Long
  1749.     Dim As decfloat s, x1, x2, tmp, tmp2
  1750.     Call fpdiv_si(x1, x, 8192, digits) ' 2^13
  1751.     Call fpmul(x2, x1, x1, digits)
  1752.     Call si2fp(s, 4 * n + 6, digits)
  1753.     For i = n To 0 Step -1
  1754.         Call si2fp(tmp, 4 * i + 2, digits)
  1755.         Call fpdiv(s, x2, s, digits)
  1756.         Call fpadd(s, s, tmp, digits)
  1757.     Next
  1758.     Call fpdiv(s, x1, s, digits)
  1759.     Call si2fp(tmp, 1, digits)
  1760.     tmp2 = tmp
  1761.     Call fpadd(tmp, tmp, s, digits)
  1762.     Call fpsub(tmp2, tmp2, s, digits)
  1763.     Call fpdiv(s, tmp, tmp2, digits)
  1764.     For i = 1 To 13 ' s^13
  1765.         Call fpmul(s, s, s, digits)
  1766.     Next
  1767.     result = s
  1768.  
  1769. Sub fplog_r (result As decfloat, x As decfloat, digits_in As Long)
  1770.     Dim As Long digits
  1771.     digits = digits_in
  1772.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1773.     '====================Log Guard==================
  1774.     Dim As decfloat x2, y, tmp
  1775.     Dim As Long i
  1776.     Dim As Long ex, terms, prec, n
  1777.     Dim As Double t, t2
  1778.  
  1779.     tmp.sign = 0
  1780.     tmp.exponent = (BIAS + 1)
  1781.     Call set(tmp.mantissa, 0, 10000000)
  1782.     For i = 1 To NUM_DWORDS
  1783.         Call set(tmp.mantissa, i, 0)
  1784.     Next
  1785.     If fpcmp(x, tmp, digits) = 0 Then result = x2: Exit Sub
  1786.     ex = (x.exponent And &H7FFFFFFF) - BIAS - 1
  1787.     t = git(x.mantissa, 0) + git(x.mantissa, 1) / 100000000
  1788.     t = t / 10000000
  1789.     t2 = Log(t) + Log(10) * ex
  1790.  
  1791.     n = Log((digits + 1) * 0.5) * 1.5
  1792.  
  1793.     Call str2fp(x2, Str$(t2))
  1794.     prec = 3
  1795.     terms = 2
  1796.     prec = 2 * prec - 1
  1797.     Call fpexp_cf(y, x2, terms, prec)
  1798.     Call fpsub(tmp, y, x, prec)
  1799.     Call fpdiv(tmp, tmp, y, prec)
  1800.     Call fpsub(x2, x2, tmp, prec)
  1801.     If digits > 4 And digits <= 9 Then
  1802.         prec = 2 * prec - 1
  1803.         terms = 2 * terms + 1
  1804.         Call fpexp_cf(y, x2, terms, prec)
  1805.         Call fpsub(tmp, y, x, prec)
  1806.         Call fpdiv(tmp, tmp, y, prec)
  1807.         Call fpsub(x2, x2, tmp, prec)
  1808.     ElseIf digits > 9 And digits < 18 Then
  1809.         For i = 1 To 3
  1810.             prec = 2 * prec - 1
  1811.             terms = 2 * terms + 1
  1812.             Call fpexp_cf(y, x2, terms, prec)
  1813.             Call fpsub(tmp, y, x, prec)
  1814.             Call fpdiv(tmp, tmp, y, prec)
  1815.             Call fpsub(x2, x2, tmp, prec)
  1816.         Next
  1817.     ElseIf digits > 17 And digits < 34 Then
  1818.         For i = 1 To 4
  1819.             prec = 2 * prec - 1
  1820.             terms = 2 * terms + 1
  1821.             Call fpexp_cf(y, x2, terms, prec)
  1822.             Call fpsub(tmp, y, x, prec)
  1823.             Call fpdiv(tmp, tmp, y, prec)
  1824.             Call fpsub(x2, x2, tmp, prec)
  1825.         Next
  1826.     ElseIf digits > 33 And digits < 65 Then
  1827.         For i = 1 To 5
  1828.             prec = 2 * prec - 1
  1829.             terms = 2 * terms + 1
  1830.             Call fpexp_cf(y, x2, terms, prec)
  1831.             Call fpsub(tmp, y, x, prec)
  1832.             Call fpdiv(tmp, tmp, y, prec)
  1833.             Call fpsub(x2, x2, tmp, prec)
  1834.         Next
  1835.     ElseIf digits > 64 Then
  1836.         For i = 1 To 6
  1837.             prec = 2 * prec - 1
  1838.             terms = 2 * terms + 1
  1839.             Call fpexp_cf(y, x2, terms, prec)
  1840.             Call fpsub(tmp, y, x, prec)
  1841.             Call fpdiv(tmp, tmp, y, prec)
  1842.             Call fpsub(x2, x2, tmp, prec)
  1843.         Next
  1844.     End If
  1845.     result = x2
  1846.  
  1847. Sub fppow (result As decfloat, lhs As decfloat, rhs As decfloat)
  1848.     Dim As decfloat lhs2
  1849.     Call fplog(lhs2, lhs, NUM_DWORDS)
  1850.     Call fpmul(lhs2, lhs2, rhs, NUM_DWORDS)
  1851.     Call fpexp(lhs2, lhs2, NUM_DWORDS)
  1852.     result = lhs2
  1853.  
  1854. Sub fpnroot (result As decfloat, x As decfloat, p As Long, digits_in As Long)
  1855.     Dim As Long digits
  1856.     digits = digits_in
  1857.     If digits > NUM_DWORDS Then digits = NUM_DWORDS
  1858.     Dim As decfloat ry, tmp, tmp2
  1859.     Dim As Double t, t2
  1860.     Dim As Long i, ex, l, prec
  1861.  
  1862.     l = Log((NUM_DIGITS + 8) * 0.0625) * 1.5
  1863.     ex = (x.exponent And &H7FFFFFFF) - BIAS - 1
  1864.     t = git(x.mantissa, 0) + git(x.mantissa, 1) / 100000000
  1865.     t = t / 10000000
  1866.     t2 = Log(t) / p + Log(10) * ex / p
  1867.     t2 = Exp(t2)
  1868.     Call str2fp(ry, Str$(t2))
  1869.     prec = 3
  1870.  
  1871.     Call fpipow(tmp, ry, p - 1, prec)
  1872.     Call fpdiv(tmp, x, tmp, prec)
  1873.     Call fpmul_si(tmp2, ry, p - 1, prec)
  1874.     Call fpadd(tmp2, tmp2, tmp, prec)
  1875.     Call fpdiv_si(ry, tmp2, p, prec)
  1876.     For i = 1 To l
  1877.         prec = 2 * prec - 1
  1878.         Call fpipow(tmp, ry, p - 1, prec)
  1879.         Call fpdiv(tmp, x, tmp, prec)
  1880.         Call fpmul_si(tmp2, ry, p - 1, prec)
  1881.         Call fpadd(tmp2, tmp2, tmp, prec)
  1882.         Call fpdiv_si(ry, tmp2, p, prec)
  1883.     Next
  1884.     result = ry
  1885.  
  1886. Sub pi_brent_salamin (pi_bs As decfloat, digits_in As Unsigned Long)
  1887.     Dim As Unsigned Long digits
  1888.     digits = digits_in
  1889.     If digits > NUMBER_OF_DIGITS Then digits = NUMBER_OF_DIGITS
  1890.  
  1891.     Dim As Long limit2
  1892.     Dim As decfloat c0, c1, c2, c05
  1893.     Dim As decfloat a, b, sum
  1894.     Dim As decfloat ak, bk, ck
  1895.     Dim As decfloat ab, asq
  1896.     Dim As decfloat pow2, tmp
  1897.  
  1898.     limit2 = -digits + BIAS + 1
  1899.     Call si2fp(c0, 0, NUMBER_OF_DIGITS): ak = c0: bk = c0: ab = c0: asq = c0
  1900.     Call si2fp(c1, 1, NUMBER_OF_DIGITS): a = c1: ck = c1: pow2 = c1
  1901.     Call si2fp(c2, 2, NUMBER_OF_DIGITS): b = c2
  1902.     Call str2fp(c05, ".5"): sum = c05
  1903.     Call si2fp(pi_bs, 3, NUMBER_OF_DIGITS)
  1904.  
  1905.     Call fpsqr(b, b, NUMBER_OF_DIGITS)
  1906.     Call fpdiv(b, c1, b, NUMBER_OF_DIGITS)
  1907.     While fpcmp(ck, c0, NUMBER_OF_DIGITS) <> 0 And ck.exponent > limit2
  1908.         Call fpadd(ak, a, b, NUMBER_OF_DIGITS)
  1909.         Call fpmul(ak, c05, ak, NUMBER_OF_DIGITS)
  1910.         Call fpmul(ab, a, b, NUMBER_OF_DIGITS)
  1911.         Call fpsqr(bk, ab, NUMBER_OF_DIGITS)
  1912.         Call fpmul(asq, ak, ak, NUMBER_OF_DIGITS)
  1913.         Call fpsub(ck, asq, ab, NUMBER_OF_DIGITS)
  1914.         Call fpmul(pow2, pow2, c2, NUMBER_OF_DIGITS)
  1915.         Call fpmul(tmp, pow2, ck, NUMBER_OF_DIGITS)
  1916.         Call fpsub(sum, sum, tmp, NUMBER_OF_DIGITS)
  1917.         a = ak: b = bk
  1918.     Wend
  1919.     Call fpdiv(tmp, asq, sum, NUMBER_OF_DIGITS)
  1920.     Call fpmul(pi_bs, c2, tmp, NUMBER_OF_DIGITS)
  1921.  
  1922. Sub fpsin (result As decfloat, x As decfloat, digits_in As Unsigned Long)
  1923.     Dim As decfloat XX, Term, Accum, p, temp2, fac, x_2
  1924.     Dim As decfloat pi2, circ, Ab
  1925.     Dim As Long precision
  1926.     precision = digits_in
  1927.  
  1928.     x_2 = x
  1929.     pi2 = pi_dec
  1930.     Call fpmul_si(circ, pi2, 2, precision)
  1931.     Call fpabs(Ab, x)
  1932.     If fpcmp(Ab, circ, precision) > 0 Then
  1933.         '======== CENTRALIZE ==============
  1934.         'floor/ceil to centralize
  1935.         Dim As decfloat tmp, tmp2
  1936.         If precision > 20 Then
  1937.             pi2 = pi_dec
  1938.         End If
  1939.         Call fpmul_si(pi2, pi2, 2, precision) 'got 2*pi
  1940.         Call fpdiv(tmp, x_2, pi2, precision)
  1941.         tmp2 = tmp
  1942.         Call fpfix(tmp, tmp) 'int part
  1943.         Call fpsub(tmp, tmp2, tmp, precision) 'frac part
  1944.         Call fpmul(tmp, tmp, pi2, precision)
  1945.         x_2 = tmp
  1946.     End If
  1947.  
  1948.     Dim As Long lm, limit2, i
  1949.     Dim As decfloat factor
  1950.     lm = precision
  1951.     limit2 = Int(-0.45344993886092585968 + 0.022333002852398072433 * lm + 5.0461814408333079844E-7 * lm * lm - 4.2338453039804235772E-11 * lm * lm * lm)
  1952.  
  1953.     Call si2fp(factor, 5, precision)
  1954.     Call fpipow(factor, factor, limit2, precision)
  1955.     Call fpdiv(x_2, x_2, factor, precision) 'x_=x_/5^limit2
  1956.     '==================================
  1957.     Dim As Long sign(3): sign(3) = 1
  1958.     Dim As Long c: c = 1
  1959.  
  1960.     Accum = x_2
  1961.     Call si2fp(fac, 1, precision)
  1962.     p = x_2
  1963.     Call fpmul(XX, x_2, x_2, precision)
  1964.     Do
  1965.         c = c + 2
  1966.         temp2 = Accum
  1967.         Call fpmul_si(fac, fac, c * (c - 1), precision)
  1968.         Call fpmul(p, p, XX, precision)
  1969.         Call fpdiv(Term, p, fac, precision)
  1970.         If sign(c And 3) Then
  1971.             Call fpsub(Accum, temp2, Term, precision)
  1972.         Else
  1973.             Call fpadd(Accum, temp2, Term, precision)
  1974.         End If
  1975.     Loop Until fpcmp(Accum, temp2, precision) = 0
  1976.     'multiply the result by 5^limit2
  1977.  
  1978.     For i = 1 To limit2
  1979.         Call fpmul(p, Accum, Accum, precision)
  1980.         Call fpmul(temp2, Accum, p, precision)
  1981.         '*** sin(5*x) = 5 * sin(x) - 20 * sin(x)^3 + 16 * sin(x)^5
  1982.         Call fpmul_si(Accum, Accum, 5, precision)
  1983.         Call fpmul_si(Term, temp2, 20, precision)
  1984.         Call fpmul_si(XX, temp2, 16, precision)
  1985.         Call fpmul(XX, XX, p, precision)
  1986.         Call fpsub(Accum, Accum, Term, precision)
  1987.         Call fpadd(Accum, Accum, XX, precision)
  1988.     Next i
  1989.     result = Accum
  1990.  
  1991. Sub fpcos (result As decfloat, z As decfloat, digits_in As Unsigned Long)
  1992.     Dim As decfloat x_2, pi2
  1993.     Dim As Long precision
  1994.     precision = digits_in
  1995.     Call fpdiv_si(pi2, pi_dec, 2, precision)
  1996.     Call fpsub(x_2, pi2, z, precision)
  1997.  
  1998.     Call fpsin(result, x_2, precision)
  1999.  
  2000. Sub fptan (result As decfloat, z As decfloat, digits_in As Unsigned Long)
  2001.     Dim As decfloat x_2, s, c
  2002.     Dim As Long precision
  2003.     precision = digits_in
  2004.     x_2 = z
  2005.     Call fpsin(s, x_2, precision)
  2006.     x_2 = z
  2007.     Call fpcos(c, x_2, precision)
  2008.     Call fpdiv(result, s, c, precision)
  2009.  
  2010. Sub fpatn (result As decfloat, x As decfloat, digits_in As Unsigned Long)
  2011.     Dim As Long precision, z
  2012.     precision = digits_in
  2013.     Dim As Long sign(3): sign(3) = 1
  2014.     Dim As Unsigned Long c: c = 1
  2015.     Dim As decfloat XX, Term, Accum, strC, x_2, mt, mt2, p
  2016.     Dim As decfloat decnum, one, decnum2, factor
  2017.  
  2018.     decnum2 = x
  2019.     decnum2.sign = 0
  2020.     Call si2fp(one, 1, precision)
  2021.     If fpcmp(decnum2, one, precision) = 0 Then
  2022.         Call fpdiv_si(result, pi_dec, 4, precision)
  2023.         result.sign = x.sign
  2024.         Exit Sub
  2025.     End If
  2026.     decnum2.sign = x.sign
  2027.     Dim As Long limit2: limit2 = 16
  2028.     Call si2fp(factor, SHL(2, limit2 - 1), precision)
  2029.     For z = 1 To limit2
  2030.         Call fpmul(decnum, decnum2, decnum2, precision)
  2031.         Call fpadd(decnum, decnum, one, precision)
  2032.         Call fpsqr(decnum, decnum, precision)
  2033.         Call fpadd(decnum, decnum, one, precision)
  2034.         Call fpdiv(decnum, decnum2, decnum, precision)
  2035.         decnum2 = decnum
  2036.     Next z
  2037.  
  2038.     mt = decnum
  2039.     x_2 = decnum
  2040.     p = decnum
  2041.     Call fpmul(XX, x_2, x_2, precision)
  2042.     Do
  2043.         c = c + 2
  2044.         mt2 = mt
  2045.         Call si2fp(strC, c, precision)
  2046.         Call fpmul(p, p, XX, precision)
  2047.         Call fpdiv(Term, p, strC, precision)
  2048.         If sign(c And 3) Then
  2049.             Call fpsub(Accum, mt, Term, precision)
  2050.         Else
  2051.             Call fpadd(Accum, mt, Term, precision)
  2052.         End If
  2053.         Swap mt, Accum
  2054.     Loop Until fpcmp(mt, mt2, precision) = 0
  2055.     Call fpmul(result, factor, mt, precision)
  2056.  
  2057. Sub fpasin (result As decfloat, x As decfloat, digits_in As Unsigned Long)
  2058.     Dim As Long precision
  2059.     precision = digits_in
  2060.     Dim As Double num
  2061.     ' ARCSIN = ATN(x / SQR(-x * x + 1))
  2062.     '============= ARCSIN GUARD =========
  2063.     num = fp2dbl(x)
  2064.     If num > 1 Then Exit Sub
  2065.     If num < -1 Then Exit Sub
  2066.     '========================
  2067.     Dim As decfloat one, T, B, term1, minusone
  2068.     Call si2fp(one, 1, precision)
  2069.     Call si2fp(minusone, -1, precision)
  2070.     T = x
  2071.     Call fpmul(B, x, x, precision) 'x*x
  2072.     'for 1 and -1
  2073.     If fpcmp(B, one, precision) = 0 Then
  2074.         Dim As decfloat two, atn1
  2075.         Call si2fp(two, 2, precision)
  2076.         Call fpatn(atn1, one, precision)
  2077.         If fpcmp(x, minusone, precision) = 0 Then
  2078.             Call fpmul(two, two, atn1, precision)
  2079.             Call fpmul(result, two, minusone, precision)
  2080.             Exit Sub
  2081.         Else
  2082.             Call fpmul(result, two, atn1, precision)
  2083.             Exit Sub
  2084.         End If
  2085.     End If
  2086.     Call fpsub(B, one, B, precision) '1-x*x
  2087.     Call fpsqr(B, B, precision) 'sqr(1-x*x)
  2088.     Call fpdiv(term1, T, B, precision)
  2089.     Call fpatn(result, term1, precision)
  2090.  
  2091. Sub fpacos (result As decfloat, x As decfloat, digits_in As Unsigned Long)
  2092.     Dim As Long precision
  2093.     precision = digits_in
  2094.     Dim As decfloat one, minusone, two, atn1, tail, T, B, term1, atnterm1 ',_x,temp
  2095.     Dim As Double num
  2096.     'ARCCOS = ATN(-x / SQR(-x * x + 1)) + 2 * ATN(1)
  2097.     '============= ARCCOS GUARD =========
  2098.     num = fp2dbl(x)
  2099.     If num > 1 Then Exit Sub
  2100.     If num < -1 Then Exit Sub
  2101.     '========================
  2102.     Call si2fp(one, 1, precision)
  2103.     Call si2fp(minusone, -1, precision)
  2104.     Call si2fp(two, 2, precision)
  2105.     Call fpatn(atn1, one, precision)
  2106.     Call fpmul(tail, two, atn1, precision) '2*atn(1)
  2107.     Call fpmul(T, minusone, x, precision) '-x
  2108.     Call fpmul(B, x, x, precision) 'x*x
  2109.     If fpcmp(B, one, precision) = 0 Then
  2110.         'for 1 and -1
  2111.         If fpcmp(x, minusone, precision) = 0 Then
  2112.             Dim As decfloat four
  2113.             Call si2fp(four, 4, precision)
  2114.             Call fpmul(result, four, atn1, precision)
  2115.             Exit Sub
  2116.         Else
  2117.             Call si2fp(result, 0, precision)
  2118.             Exit Sub
  2119.         End If
  2120.     End If
  2121.     Call fpsub(B, one, B, precision) '1-x*x
  2122.     Call fpsqr(B, B, precision) 'sqr(1-x*x)
  2123.     Call fpdiv(term1, T, B, precision)
  2124.     Call fpatn(atnterm1, term1, precision)
  2125.     Call fpadd(result, atnterm1, tail, precision)
  2126.  
output
Code: [Select]
factorial(10000) to  512  digits
 2.8462596809170545189064132121198688901480514017027992307941799942744113400037644437729907867577847758158840621423175288300423399401535187390524211613827161748198241998275924182892597878981242531205946599625986706560161572036032397926328736717055741975962099479720346153698119897092611277500484198845410475544642442136573303076703628825803548967461117097369578603670191071512730587281041158640561281165385325968425825995584688146430425589836649317059251717204276597407446133400054194052462303436869154059404066227E+35659

in  .494140625  seconds

3/9 to  512  digits
 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

in  0  seconds

and square it
 0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

ln(2) to  512  digits
 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023575813055703267075163507596193072757082837143519030703862389167347112335011536449795523912047517268157493206515552473413952588295045300709532636664265410423915781495204374043038550080194417064167151864471283996817178454695702627163106454615025720740248163777338963855069526066834113727387372292895649354702576265209885969320196505855476470330679365443254763274495125040606943814710468

in  .111328125  seconds

and the inverse
 1.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

in  .21875  seconds

reciprocal of 3
 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

in  0  seconds

Press any key to continue

10
Programs / BlowFish encryption
« on: October 08, 2021, 01:27:53 pm »
in my test when decrypting a text file all is good except that there are a few garbage characters at the end of the file, perhaps you may want to fix that, or not
Code: QB64: [Select]
  1.  
  2.  
  3. Const MAXKEYBYTES = 56
  4. Const N = 16
  5. Const low_bound = 3
  6. Const high_bound = 255
  7. Const num_elements_size = (low_bound + 1) * (high_bound + 1) * 4
  8. Const array_offset = 4 * high_bound ' 4 is the size of a ulong
  9.  
  10. Type blowfish_ctx
  11.     p As String * 72 ' (n + 2) * 4 or p(0 to n+1)
  12.     s As String * Num_elements_size ' array(3, 255) of ulong
  13.  
  14. Dim Shared orig_p(0 To (16 + 2) - 1) As _Unsigned Long
  15. Dim Shared orig_s(0 To 3, 0 To 255) As _Unsigned Long
  16.  
  17. Call initialize
  18.  
  19. Dim As blowfish_ctx ctx
  20. l = 1
  21. r = 2
  22. Call blowfish_init(ctx, "TESTKEY", 7)
  23. Call blowfish_encrypt(ctx, l, r)
  24. Call Blowfish_Decrypt(ctx, l, r)
  25. Dim As String passwd
  26. passwd = "TESTKEY"
  27. Call blowfish_init(ctx, passwd, Len(passwd))
  28. Open "test.txt" For Binary As #1
  29. Open "test_enc.txt" For Binary As #2
  30.  
  31.     Get #1, , l
  32.     Get #1, , r
  33.     Call blowfish_encrypt(ctx, l, r)
  34.     Put #2, , l
  35.     Put #2, , r
  36. Close 1, 2
  37. 'passwd = "TESTKEY"
  38. 'call Blowfish_Init(ctx, passwd, Len(passwd))
  39. Open "test_enc.txt" For Binary As #1
  40. Open "test_dec.txt" For Binary As #2
  41.  
  42.     Get #1, , l
  43.     Get #1, , r
  44.     Call Blowfish_Decrypt(ctx, l, r)
  45.     Put #2, , l
  46.     Put #2, , r
  47. Close 1, 2
  48.  
  49. Sub initialize
  50.     Dim ct As Integer
  51.     For ct = 0 To 17
  52.         Read orig_p(ct)
  53.     Next ct
  54.     For ct = 0 To 255
  55.         Read orig_s(0, ct)
  56.     Next ct
  57.     For ct = 0 To 255
  58.         Read orig_s(1, ct)
  59.     Next ct
  60.     For ct = 0 To 255
  61.         Read orig_s(2, ct)
  62.     Next ct
  63.     For ct = 0 To 255
  64.         Read orig_s(3, ct)
  65.     Next ct
  66.  
  67. Function idx1& (i&)
  68.     idx1 = 4 * i& + 1
  69.  
  70. Function idx2& (i&, j&)
  71.     idx2 = array_offset * i& + 4 * i& + 4 * j& + 1
  72.  
  73. Sub set1 (s$, i&, v~&)
  74.     Mid$(s$, 4 * i& + 1, 4) = MKL$(v~&)
  75.  
  76. Function get1~& (s$, i&)
  77.     get1 = CVL(Mid$(s$, 4 * i& + 1, 4))
  78.  
  79. Sub set2 (s$, i&, j&, v~&)
  80.     Mid$(s$, array_offset * i& + 4 * i& + 4 * j& + 1, 4) = MKL$(v~&)
  81.  
  82. Function get2~& (s$, i&, j&)
  83.     get2 = CVL(Mid$(s$, array_offset * i& + 4 * i& + 4 * j& + 1, 4))
  84.  
  85. Function f~& (ctx As blowfish_ctx, x1 As _Unsigned Long)
  86.     Dim As _Unsigned Integer a, b, c, d
  87.     Dim As _Unsigned Long x, y
  88.     x = x1
  89.     d = x And &H00FF
  90.     x = _SHR(x, 8)
  91.     c = x And &H00FF
  92.     x = _SHR(x, 8)
  93.     b = x And &H00FF
  94.     x = _SHR(x, 8)
  95.     a = x And &H00FF
  96.     y = get2(ctx.s, 0, a) + get2(ctx.s, 1, b)
  97.     y = y Xor get2(ctx.s, 2, c)
  98.     y = y + get2(ctx.s, 3, d)
  99.     f = y
  100.  
  101. Sub blowfish_encrypt (ctx As blowfish_ctx, xl As _Unsigned Long, xr As _Unsigned Long)
  102.     Dim As _Unsigned Long x_l, x_r, temp
  103.     Dim i As Long
  104.     x_l = xl
  105.     x_r = xr
  106.  
  107.     For i = 0 To N - 1
  108.         x_l = x_l Xor get1(ctx.p, i)
  109.         x_r = f(ctx, x_l) Xor x_r
  110.         temp = x_l
  111.         x_l = x_r
  112.         x_r = temp
  113.     Next
  114.     temp = x_l
  115.     x_l = x_r
  116.     x_r = temp
  117.     x_r = x_r Xor get1(ctx.p, 16)
  118.     x_l = x_l Xor get1(ctx.p, (16 + 1))
  119.     xl = x_l
  120.     xr = x_r
  121.  
  122. Sub Blowfish_Decrypt (ctx As blowfish_ctx, xl As _Unsigned Long, xr As _Unsigned Long)
  123.     Dim As _Unsigned Long X_l, X_r, temp
  124.     Dim i As Long
  125.     X_l = xl
  126.     X_r = xr
  127.     For i = N + 1 To 2 Step -1
  128.         X_l = X_l Xor get1(ctx.p, i)
  129.         X_r = f(ctx, X_l) Xor X_r
  130.         temp = X_l
  131.         X_l = X_r
  132.         X_r = temp
  133.     Next
  134.     temp = X_l
  135.     X_l = X_r
  136.     X_r = temp
  137.     X_r = X_r Xor get1(ctx.p, 1)
  138.     X_l = X_l Xor get1(ctx.p, 0)
  139.     xl = X_l
  140.     xr = X_r
  141.  
  142. Sub blowfish_init (ctx As blowfish_ctx, pass_key As String, keylen As Long)
  143.     Dim As Long i, j, k
  144.     Dim As _Unsigned Long data2, datal, datar
  145.     For i = 0 To 3
  146.         For j = 0 To 255
  147.             Call set2(ctx.s, i, j, orig_s(i, j))
  148.         Next
  149.     Next
  150.     j = 0
  151.     For i = 0 To N + 1
  152.         data2 = 0
  153.         For k = 0 To 3
  154.             data2 = _SHL(data2, 8) Or Asc(pass_key, j + 1)
  155.             j = j + 1
  156.             If j >= keylen Then
  157.                 j = 0
  158.             End If
  159.         Next
  160.         Call set1(ctx.p, i, orig_p(i) Xor data2)
  161.     Next
  162.     datal = 0
  163.     datar = 0
  164.     For i = 0 To N + 1 Step 2
  165.         Call blowfish_encrypt(ctx, datal, datar)
  166.         Call set1(ctx.p, i, datal)
  167.         Call set1(ctx.p, i + 1, datar)
  168.     Next
  169.     For i = 0 To 3
  170.         For j = 0 To 255 Step 2
  171.             Call blowfish_encrypt(ctx, datal, datar)
  172.             Call set2(ctx.s, i, j, datal)
  173.             Call set2(ctx.s, i, j + 1, datar)
  174.         Next
  175.     Next
  176.  
  177. Data &H243F6A88,&H85A308D3,&H13198A2E,&H3707344
  178. Data &HA4093822,&H299F31D0,&H82EFA98,&HEC4E6C89
  179. Data &H452821E6,&H38D01377,&HBE5466CF,&H34E90C6C
  180. Data &HC0AC29B7,&HC97C50DD,&H3F84D5B5,&HB5470917
  181. Data &H9216D5D9,&H8979FB1B
  182.  
  183. Data &HD1310BA6,&H98DFB5AC,&H2FFD72DB,&HD01ADFB7
  184. Data &HB8E1AFED,&H6A267E96,&HBA7C9045,&HF12C7F99
  185. Data &H24A19947,&HB3916CF7,&H801F2E2,&H858EFC16
  186. Data &H636920D8,&H71574E69,&HA458FEA3,&HF4933D7E
  187. Data &HD95748F,&H728EB658,&H718BCD58,&H82154AEE
  188. Data &H7B54A41D,&HC25A59B5,&H9C30D539,&H2AF26013
  189. Data &HC5D1B023,&H286085F0,&HCA417918,&HB8DB38EF
  190. Data &H8E79DCB0,&H603A180E,&H6C9E0E8B,&HB01E8A3E
  191. Data &HD71577C1,&HBD314B27,&H78AF2FDA,&H55605C60
  192. Data &HE65525F3,&HAA55AB94,&H57489862,&H63E81440
  193. Data &H55CA396A,&H2AAB10B6,&HB4CC5C34,&H1141E8CE
  194. Data &HA15486AF,&H7C72E993,&HB3EE1411,&H636FBC2A
  195. Data &H2BA9C55D,&H741831F6,&HCE5C3E16,&H9B87931E
  196. Data &HAFD6BA33,&H6C24CF5C,&H7A325381,&H28958677
  197. Data &H3B8F4898,&H6B4BB9AF,&HC4BFE81B,&H66282193
  198. Data &H61D809CC,&HFB21A991,&H487CAC60,&H5DEC8032
  199.  
  200. Data &HEF845D5D,&HE98575B1,&HDC262302,&HEB651B88
  201. Data &H23893E81,&HD396ACC5,&HF6D6FF3,&H83F44239
  202. Data &H2E0B4482,&HA4842004,&H69C8F04A,&H9E1F9B5E
  203. Data &H21C66842,&HF6E96C9A,&H670C9C61,&HABD388F0
  204. Data &H6A51A0D2,&HD8542F68,&H960FA728,&HAB5133A3
  205. Data &H6EEF0B6C,&H137A3BE4,&HBA3BF050,&H7EFB2A98
  206. Data &HA1F1651D,&H39AF0176,&H66CA593E,&H82430E88
  207. Data &H8CEE8619,&H456F9FB4,&H7D84A5C3,&H3B8B5EBE
  208. Data &HE06F75D8,&H85C12073,&H401A449F,&H56C16AA6
  209. Data &H4ED3AA62,&H363F7706,&H1BFEDF72,&H429B023D
  210. Data &H37D0D724,&HD00A1248,&HDB0FEAD3,&H49F1C09B
  211. Data &H75372C9,&H80991B7B,&H25D479D8,&HF6E8DEF7
  212. Data &HE3FE501A,&HB6794C3B,&H976CE0BD,&H4C006BA
  213. Data &HC1A94FB6,&H409F60C4,&H5E5C9EC2,&H196A2463
  214. Data &H68FB6FAF,&H3E6C53B5,&H1339B2EB,&H3B52EC6F
  215. Data &H6DFC511F,&H9B30952C,&HCC814544,&HAF5EBD09
  216.  
  217. Data &HBEE3D004,&HDE334AFD,&H660F2807,&H192E4BB3
  218. Data &HC0CBA857,&H45C8740F,&HD20B5F39,&HB9D3FBDB
  219. Data &H5579C0BD,&H1A60320A,&HD6A100C6,&H402C7279
  220. Data &H679F25FE,&HFB1FA3CC,&H8EA5E9F8,&HDB3222F8
  221. Data &H3C7516DF,&HFD616B15,&H2F501EC8,&HAD0552AB
  222. Data &H323DB5FA,&HFD238760,&H53317B48,&H3E00DF82
  223. Data &H9E5C57BB,&HCA6F8CA0,&H1A87562E,&HDF1769DB
  224. Data &HD542A8F6,&H287EFFC3,&HAC6732C6,&H8C4F5573
  225. Data &H695B27B0,&HBBCA58C8,&HE1FFA35D,&HB8F011A0
  226. Data &H10FA3D98,&HFD2183B8,&H4AFCB56C,&H2DD1D35B
  227. Data &H9A53E479,&HB6F84565,&HD28E49BC,&H4BFB9790
  228. Data &HE1DDF2DA,&HA4CB7E33,&H62FB1341,&HCEE4C6E8
  229. Data &HEF20CADA,&H36774C01,&HD07E9EFE,&H2BF11FB4
  230. Data &H95DBDA4D,&HAE909198,&HEAAD8E71,&H6B93D5A0
  231. Data &HD08ED1D0,&HAFC725E0,&H8E3C5B2F,&H8E7594B7
  232. Data &H8FF6E2FB,&HF2122B64,&H8888B812,&H900DF01C
  233.  
  234. Data &H4FAD5EA0,&H688FC31C,&HD1CFF191,&HB3A8C1AD
  235. Data &H2F2F2218,&HBE0E1777,&HEA752DFE,&H8B021FA1
  236. Data &HE5A0CC0F,&HB56F74E8,&H18ACF3D6,&HCE89E299
  237. Data &HB4A84FE0,&HFD13E0B7,&H7CC43B81,&HD2ADA8D9
  238. Data &H165FA266,&H80957705,&H93CC7314,&H211A1477
  239. Data &HE6AD2065,&H77B5FA86,&HC75442F5,&HFB9D35CF
  240. Data &HEBCDAF0C,&H7B3E89A0,&HD6411BD3,&HAE1E7E49
  241. Data &H250E2D,&H2071B35E,&H226800BB,&H57B8E0AF
  242. Data &H2464369B,&HF009B91E,&H5563911D,&H59DFA6AA
  243. Data &H78C14389,&HD95A537F,&H207D5BA2,&H2E5B9C5
  244. Data &H83260376,&H6295CFA9,&H11C81968,&H4E734A41
  245. Data &HB3472DCA,&H7B14A94A,&H1B510052,&H9A532915
  246. Data &HD60F573F,&HBC9BC6E4,&H2B60A476,&H81E67400
  247. Data &H8BA6FB5,&H571BE91F,&HF296EC6B,&H2A0DD915
  248. Data &HB6636521,&HE7B9F9B6,&HFF34052E,&HC5855664
  249. Data &H53B02D5D,&HA99F8FA1,&H8BA4799,&H6E85076A
  250.  
  251. Data &H4B7A70E9,&HB5B32944,&HDB75092E,&HC4192623
  252. Data &HAD6EA6B0,&H49A7DF7D,&H9CEE60B8,&H8FEDB266
  253. Data &HECAA8C71,&H699A17FF,&H5664526C,&HC2B19EE1
  254. Data &H193602A5,&H75094C29,&HA0591340,&HE4183A3E
  255. Data &H3F54989A,&H5B429D65,&H6B8FE4D6,&H99F73FD6
  256. Data &HA1D29C07,&HEFE830F5,&H4D2D38E6,&HF0255DC1
  257. Data &H4CDD2086,&H8470EB26,&H6382E9C6,&H21ECC5E
  258. Data &H9686B3F,&H3EBAEFC9,&H3C971814,&H6B6A70A1
  259. Data &H687F3584,&H52A0E286,&HB79C5305,&HAA500737
  260. Data &H3E07841C,&H7FDEAE5C,&H8E7D44EC,&H5716F2B8
  261. Data &HB03ADA37,&HF0500C0D,&HF01C1F04,&H200B3FF
  262. Data &HAE0CF51A,&H3CB574B2,&H25837A58,&HDC0921BD
  263. Data &HD19113F9,&H7CA92FF6,&H94324773,&H22F54701
  264. Data &H3AE5E581,&H37C2DADC,&HC8B57634,&H9AF3DDA7
  265. Data &HA9446146,&HFD0030E,&HECC8C73E,&HA4751E41
  266. Data &HE238CD99,&H3BEA0E2F,&H3280BBA1,&H183EB331
  267.  
  268. Data &H4E548B38,&H4F6DB908,&H6F420D03,&HF60A04BF
  269. Data &H2CB81290,&H24977C79,&H5679B072,&HBCAF89AF
  270. Data &HDE9A771F,&HD9930810,&HB38BAE12,&HDCCF3F2E
  271. Data &H5512721F,&H2E6B7124,&H501ADDE6,&H9F84CD87
  272. Data &H7A584718,&H7408DA17,&HBC9F9ABC,&HE94B7D8C
  273. Data &HEC7AEC3A,&HDB851DFA,&H63094366,&HC464C3D2
  274. Data &HEF1C1847,&H3215D908,&HDD433B37,&H24C2BA16
  275. Data &H12A14D43,&H2A65C451,&H50940002,&H133AE4DD
  276. Data &H71DFF89E,&H10314E55,&H81AC77D6,&H5F11199B
  277. Data &H43556F1,&HD7A3C76B,&H3C11183B,&H5924A509
  278. Data &HF28FE6ED,&H97F1FBFA,&H9EBABF2C,&H1E153C6E
  279. Data &H86E34570,&HEAE96FB1,&H860E5E0A,&H5A3E2AB3
  280. Data &H771FE71C,&H4E3D06FA,&H2965DCB9,&H99E71D0F
  281. Data &H803E89D6,&H5266C825,&H2E4CC978,&H9C10B36A
  282. Data &HC6150EBA,&H94E2EA78,&HA5FC3C53,&H1E0A2DF4
  283. Data &HF2F74EA7,&H361D2B3D,&H1939260F,&H19C27960
  284.  
  285. Data &H5223A708,&HF71312B6,&HEBADFE6E,&HEAC31F66
  286. Data &HE3BC4595,&HA67BC883,&HB17F37D1,&H18CFF28
  287. Data &HC332DDEF,&HBE6C5AA5,&H65582185,&H68AB9802
  288. Data &HEECEA50F,&HDB2F953B,&H2AEF7DAD,&H5B6E2F84
  289. Data &H1521B628,&H29076170,&HECDD4775,&H619F1510
  290. Data &H13CCA830,&HEB61BD96,&H334FE1E,&HAA0363CF
  291. Data &HB5735C90,&H4C70A239,&HD59E9E0B,&HCBAADE14
  292. Data &HEECC86BC,&H60622CA7,&H9CAB5CAB,&HB2F3846E
  293. Data &H648B1EAF,&H19BDF0CA,&HA02369B9,&H655ABB50
  294. Data &H40685A32,&H3C2AB4B3,&H319EE9D5,&HC021B8F7
  295. Data &H9B540B19,&H875FA099,&H95F7997E,&H623D7DA8
  296. Data &HF837889A,&H97E32D77,&H11ED935F,&H16681281
  297. Data &HE358829,&HC7E61FD6,&H96DEDFA1,&H7858BA99
  298. Data &H57F584A5,&H1B227263,&H9B83C3FF,&H1AC24696
  299. Data &HCDB30AEB,&H532E3054,&H8FD948E4,&H6DBC3128
  300. Data &H58EBF2EF,&H34C6FFEA,&HFE28ED61,&HEE7C3C73
  301.  
  302. Data &H5D4A14D9,&HE864B7E3,&H42105D14,&H203E13E0
  303. Data &H45EEE2B6,&HA3AAABEA,&HDB6C4F15,&HFACB4FD0
  304. Data &HC742F442,&HEF6ABBB5,&H654F3B1D,&H41CD2105
  305. Data &HD81E799E,&H86854DC7,&HE44B476A,&H3D816250
  306. Data &HCF62A1F2,&H5B8D2646,&HFC8883A0,&HC1C7B6A3
  307. Data &H7F1524C3,&H69CB7492,&H47848A0B,&H5692B285
  308. Data &H95BBF00,&HAD19489D,&H1462B174,&H23820E00
  309. Data &H58428D2A,&HC55F5EA,&H1DADF43E,&H233F7061
  310. Data &H3372F092,&H8D937E41,&HD65FECF1,&H6C223BDB
  311. Data &H7CDE3759,&HCBEE7460,&H4085F2A7,&HCE77326E
  312. Data &HA6078084,&H19F8509E,&HE8EFD855,&H61D99735
  313. Data &HA969A7AA,&HC50C06C2,&H5A04ABFC,&H800BCADC
  314. Data &H9E447A2E,&HC3453484,&HFDD56705,&HE1E9EC9
  315. Data &HDB73DBD3,&H105588CD,&H675FDA79,&HE3674340
  316. Data &HC5C43465,&H713E38D8,&H3D28F89E,&HF16DFF20
  317. Data &H153E21E7,&H8FB03D4A,&HE6E39F2B,&HDB83ADF7
  318.  
  319. Data &HE93D5A68,&H948140F7,&HF64C261C,&H94692934
  320. Data &H411520F7,&H7602D4F7,&HBCF46B2E,&HD4A20068
  321. Data &HD4082471,&H3320F46A,&H43B7D4B7,&H500061AF
  322. Data &H1E39F62E,&H97244546,&H14214F74,&HBF8B8840
  323. Data &H4D95FC1D,&H96B591AF,&H70F4DDD3,&H66A02F45
  324. Data &HBFBC09EC,&H3BD9785,&H7FAC6DD0,&H31CB8504
  325. Data &H96EB27B3,&H55FD3941,&HDA2547E6,&HABCA0A9A
  326. Data &H28507825,&H530429F4,&HA2C86DA,&HE9B66DFB
  327. Data &H68DC1462,&HD7486900,&H680EC0A4,&H27A18DEE
  328. Data &H4F3FFEA2,&HE887AD8C,&HB58CE006,&H7AF4D6B6
  329. Data &HAACE1E7C,&HD3375FEC,&HCE78A399,&H406B2A42
  330. Data &H20FE9E35,&HD9F385B9,&HEE39D7AB,&H3B124E8B
  331. Data &H1DC9FAF7,&H4B6D1856,&H26A36631,&HEAE397B2
  332. Data &H3A6EFA74,&HDD5B4332,&H6841E7F7,&HCA7820FB
  333. Data &HFB0AF54E,&HD8FEB397,&H454056AC,&HBA489527
  334. Data &H55533A3A,&H20838D87,&HFE6BA9B7,&HD096954B
  335.  
  336. Data &H55A867BC,&HA1159A58,&HCCA92963,&H99E1DB33
  337. Data &HA62A4A56,&H3F3125F9,&H5EF47E1C,&H9029317C
  338. Data &HFDF8E802,&H4272F70,&H80BB155C,&H5282CE3
  339. Data &H95C11548,&HE4C66D22,&H48C1133F,&HC70F86DC
  340. Data &H7F9C9EE,&H41041F0F,&H404779A4,&H5D886E17
  341. Data &H325F51EB,&HD59BC0D1,&HF2BCC18F,&H41113564
  342. Data &H257B7834,&H602A9C60,&HDFF8E8A3,&H1F636C1B
  343. Data &HE12B4C2,&H2E1329E,&HAF664FD1,&HCAD18115
  344. Data &H6B2395E0,&H333E92E1,&H3B240B62,&HEEBEB922
  345. Data &H85B2A20E,&HE6BA0D99,&HDE720C8C,&H2DA2F728
  346. Data &HD0127845,&H95B794FD,&H647D0862,&HE7CCF5F0
  347. Data &H5449A36F,&H877D48FA,&HC39DFD27,&HF33E8D1E
  348. Data &HA476341,&H992EFF74,&H3A6F6EAB,&HF4F8FD37
  349. Data &HA812DC60,&HA1EBDDF8,&H991BE14C,&HDB6E6B0D
  350. Data &HC67B5510,&H6D672C37,&H2765D43B,&HDCD0E804
  351. Data &HF1290DC7,&HCC00FFA3,&HB5390F92,&H690FED0B
  352.  
  353. Data &H667B9FFB,&HCEDB7D9C,&HA091CF0B,&HD9155EA3
  354. Data &HBB132F88,&H515BAD24,&H7B9479BF,&H763BD6EB
  355. Data &H37392EB3,&HCC115979,&H8026E297,&HF42E312D
  356. Data &H6842ADA7,&HC66A2B3B,&H12754CCC,&H782EF11C
  357. Data &H6A124237,&HB79251E7,&H6A1BBE6,&H4BFB6350
  358. Data &H1A6B1018,&H11CAEDFA,&H3D25BDD8,&HE2E1C3C9
  359. Data &H44421659,&HA121386,&HD90CEC6E,&HD5ABEA2A
  360. Data &H64AF674E,&HDA86A85F,&HBEBFE988,&H64E4C3FE
  361. Data &H9DBC8057,&HF0F7C086,&H60787BF8,&H6003604D
  362. Data &HD1FD8346,&HF6381FB0,&H7745AE04,&HD736FCCC
  363. Data &H83426B33,&HF01EAB71,&HB0804187,&H3C005E5F
  364. Data &H77A057BE,&HBDE8AE24,&H55464299,&HBF582E61
  365. Data &H4E58F48F,&HF2DDFDA2,&HF474EF38,&H8789BDC2
  366. Data &H5366F9C3,&HC8B38E74,&HB475F255,&H46FCD9B9
  367. Data &H7AEB2661,&H8B1DDF84,&H846A0E79,&H915F95E2
  368. Data &H466E598E,&H20B45770,&H8CD55591,&HC902DE4C
  369.  
  370. Data &HB90BACE1,&HBB8205D0,&H11A86248,&H7574A99E
  371. Data &HB77F19B6,&HE0A9DC09,&H662D09A1,&HC4324633
  372. Data &HE85A1F02,&H9F0BE8C,&H4A99A025,&H1D6EFE10
  373. Data &H1AB93D1D,&HBA5A4DF,&HA186F20F,&H2868F169
  374. Data &HDCB7DA83,&H573906FE,&HA1E2CE9B,&H4FCD7F52
  375. Data &H50115E01,&HA70683FA,&HA002B5C4,&HDE6D027
  376. Data &H9AF88C27,&H773F8641,&HC3604C06,&H61A806B5
  377. Data &HF0177A28,&HC0F586E0,&H6058AA,&H30DC7D62
  378. Data &H11E69ED7,&H2338EA63,&H53C2DD94,&HC2C21634
  379. Data &HBBCBEE56,&H90BCB6DE,&HEBFC7DA1,&HCE591D76
  380. Data &H6F05E409,&H4B7C0188,&H39720A3D,&H7C927C24
  381. Data &H86E3725F,&H724D9DB9,&H1AC15BB4,&HD39EB8FC
  382. Data &HED545578,&H8FCA5B5,&HD83D7CD3,&H4DAD0FC4
  383. Data &H1E50EF5E,&HB161E6F8,&HA28514D9,&H6C51133C
  384. Data &H6FD5C7E7,&H56E14EC4,&H362ABFCE,&HDDC6C837
  385. Data &HD79A3234,&H92638212,&H670EFA8E,&H406000E0
  386.  
  387. Data &H3A39CE37,&HD3FAF5CF,&HABC27737,&H5AC52D1B
  388. Data &H5CB0679E,&H4FA33742,&HD3822740,&H99BC9BBE
  389. Data &HD5118E9D,&HBF0F7315,&HD62D1C7E,&HC700C47B
  390. Data &HB78C1B6B,&H21A19045,&HB26EB1BE,&H6A366EB4
  391. Data &H5748AB2F,&HBC946E79,&HC6A376D2,&H6549C2C8
  392. Data &H530FF8EE,&H468DDE7D,&HD5730A1D,&H4CD04DC6
  393. Data &H2939BBDB,&HA9BA4650,&HAC9526E8,&HBE5EE304
  394. Data &HA1FAD5F0,&H6A2D519A,&H63EF8CE2,&H9A86EE22
  395. Data &HC089C2B8,&H43242EF6,&HA51E03AA,&H9CF2D0A4
  396. Data &H83C061BA,&H9BE96A4D,&H8FE51550,&HBA645BD6
  397. Data &H2826A2F9,&HA73A3AE1,&H4BA99586,&HEF5562E9
  398. Data &HC72FEFD3,&HF752F7DA,&H3F046F69,&H77FA0A59
  399. Data &H80E4A915,&H87B08601,&H9B09E6AD,&H3B3EE593
  400. Data &HE990FD5A,&H9E34D797,&H2CF0B7D9,&H22B8B51
  401. Data &H96D5AC3A,&H17DA67D,&HD1CF3ED6,&H7C7D2D28
  402. Data &H1F9F25CF,&HADF2B89B,&H5AD6B472,&H5A88F54C
  403.  
  404. Data &HE029AC71,&HE019A5E6,&H47B0ACFD,&HED93FA9B
  405. Data &HE8D3C48D,&H283B57CC,&HF8D56629,&H79132E28
  406. Data &H785F0191,&HED756055,&HF7960E44,&HE3D35E8C
  407. Data &H15056DD4,&H88F46DBA,&H3A16125,&H564F0BD
  408. Data &HC3EB9E15,&H3C9057A2,&H97271AEC,&HA93A072A
  409. Data &H1B3F6D9B,&H1E6321F5,&HF59C66FB,&H26DCF319
  410. Data &H7533D928,&HB155FDF5,&H3563482,&H8ABA3CBB
  411. Data &H28517711,&HC20AD9F8,&HABCC5167,&HCCAD925F
  412. Data &H4DE81751,&H3830DC8E,&H379D5862,&H9320F991
  413. Data &HEA7A90C2,&HFB3E7BCE,&H5121CE64,&H774FBE32
  414. Data &HA8B6E37E,&HC3293D46,&H48DE5369,&H6413E680
  415. Data &HA2AE0810,&HDD6DB224,&H69852DFD,&H9072166
  416. Data &HB39A460A,&H6445C0DD,&H586CDECF,&H1C20C8AE
  417. Data &H5BBEF7DD,&H1B588D40,&HCCD2017F,&H6BB4E3BB
  418. Data &HDDA26A7E,&H3A59FF45,&H3E350A44,&HBCB4CDD5
  419. Data &H72EACEA8,&HFA6484BB,&H8D6612AE,&HBF3C6F47
  420.  
  421. Data &HD29BE463,&H542F5D9E,&HAEC2771B,&HF64E6370
  422. Data &H740E0D8D,&HE75B1357,&HF8721671,&HAF537D5D
  423. Data &H4040CB08,&H4EB4E2CC,&H34D2466A,&H115AF84
  424. Data &HE1B00428,&H95983A1D,&H6B89FB4,&HCE6EA048
  425. Data &H6F3F3B82,&H3520AB82,&H11A1D4B,&H277227F8
  426. Data &H611560B1,&HE7933FDC,&HBB3A792B,&H344525BD
  427. Data &HA08839E1,&H51CE794B,&H2F32C9B7,&HA01FBAC9
  428. Data &HE01CC87E,&HBCC7D1F6,&HCF0111C3,&HA1E8AAC7
  429. Data &H1A908749,&HD44FBD9A,&HD0DADECB,&HD50ADA38
  430. Data &H339C32A,&HC6913667,&H8DF9317C,&HE0B12B4F
  431. Data &HF79E59B7,&H43F5BB3A,&HF2D519FF,&H27D9459C
  432. Data &HBF97222C,&H15E6FC2A,&HF91FC71,&H9B941525
  433. Data &HFAE59361,&HCEB69CEB,&HC2A86459,&H12BAA8D1
  434. Data &HB6C1075E,&HE3056A0C,&H10D25065,&HCB03A442
  435. Data &HE0EC6E0E,&H1698DB3B,&H4C98A0BE,&H3278E964
  436. Data &H9F1F9532,&HE0D392DF,&HD3A0342B,&H8971F21E
  437.  
  438. Data &H1B0A7441,&H4BA3348C,&HC5BE7120,&HC37632D8
  439. Data &HDF359F8D,&H9B992F2E,&HE60B6F47,&HFE3F11D
  440. Data &HE54CDA54,&H1EDAD891,&HCE6279CF,&HCD3E7E6F
  441. Data &H1618B166,&HFD2C1D05,&H848FD2C5,&HF6FB2299
  442. Data &HF523F357,&HA6327623,&H93A83531,&H56CCCD02
  443. Data &HACF08162,&H5A75EBB5,&H6E163697,&H88D273CC
  444. Data &HDE966292,&H81B949D0,&H4C50901B,&H71C65614
  445. Data &HE6C6C7BD,&H327A140A,&H45E1D006,&HC3F27B9A
  446. Data &HC9AA53FD,&H62A80F00,&HBB25BFE2,&H35BDD2F6
  447. Data &H71126905,&HB2040222,&HB6CBCF7C,&HCD769C2B
  448. Data &H53113EC0,&H1640E3D3,&H38ABBD60,&H2547ADF0
  449. Data &HBA38209C,&HF746CE76,&H77AFA1C5,&H20756060
  450. Data &H85CBFE4E,&H8AE88DD8,&H7AAAF9B0,&H4CF9AA7E
  451. Data &H1948C25C,&H2FB8A8C,&H1C36AE4,&HD6EBE1F9
  452. Data &H90D4F869,&HA65CDEA0,&H3F09252D,&HC208E69F
  453. Data &HB74E6132,&HCE77E25B,&H578FDFE3,&H3AC372E6
  454.  

11
QB64 Discussion / Neville Interpolation
« on: September 26, 2021, 04:11:13 am »
the recent talk about recursive functions reminded me of the Neville's method for polynomial interpolation which can easily be defined as a recursive function
Code: QB64: [Select]
  1. Dim As Double x(0 To 6), y(0 To 6)
  2. x(0) = 100: x(1) = 200: x(2) = 300: x(3) = 400: x(4) = 500: x(5) = 600: x(6) = 700
  3. y(0) = 232: y(1) = 231: y(2) = 313: y(3) = 404: y(4) = 357: y(5) = 361: y(6) = 218
  4.  
  5. Print Neville(0, 6, x(), y(), 50)
  6.  
  7. Function Neville# (i As Long, j As Long, x() As Double, y() As Double, z As Double)
  8.     If i = j Then
  9.         Neville = y(i)
  10.     Else
  11.         Neville = ((x(j) - z) * Neville(i, j - 1, x(), y(), z) + (z - x(i)) * Neville(i + 1, j, x(), y(), z)) / (x(j) - x(i))
  12.     End If
  13.  

12
QB64 Discussion / print _Float
« on: September 22, 2021, 01:34:40 pm »
QB64 print statement converts _Float to double so the range and precision of the output is that of double
libqb.cpp
Code: C: [Select]
  1. qbs *qbs_str(long double value){
  2.     //not fully implemented
  3.     return qbs_str((double)value);
  4. }
  5.  
here's QB64 code to help with that
Code: QB64: [Select]
  1.     Sub snprintf (Dest As String, Byval l As Long, frmt As String, Byval x As Double)
  2.  
  3.  
  4. x = 3.1415926535897932384626433832795F314
  5. Print strf(x)
  6. x = -x
  7. Print strf(x)
  8.  
  9. Function strf$ (x As _Float)
  10.     Dim As String s
  11.     Dim As String frmt
  12.     Dim As Long ex
  13.     s = Spc(64)
  14.     frmt = "%.19Lg" + Chr$(0)
  15.     Call snprintf(s, Len(s), frmt, x)
  16.     s = _Trim$(s)
  17.     ex = InStr(s, "e")
  18.     If ex > 0 Then Mid$(s, ex, 1) = "F"
  19.     If Left$(s, 1) <> "-" Then s = " " + s
  20.     strf = s
  21.  
I thought about editing qbs_str but the cpp code looks too complicated

13
QB64 Discussion / Arbitrary Precision
« on: September 18, 2021, 12:40:06 am »
every now and then someone asks about high precision arithmetic/math functions to be used in QB64, I came across a package that's in 4 includes http://www.hvks.com/Numerical/arbitrary_precision.html, here's the license
Quote
Copyright & License Information's

Copyright (c) 2020 Henrik Vestermark

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Furthermore if you want to be granted sublicense, and/or sell copies of the Software even when the software is only included as a library for another application, that will require a one-time fee of 1,000USD to be granted sublicense and selling right.

Please use the contact form for any inquiries about Copyright and License information's.
so as long as you don't want to sell your programs that incorporate this code you are good to go
I have tested the code a bit in g++ and it seems OK, it should be possible to call it from QB64, and there's no need to compile to a library for you to use it, the only thing you need to be aware of is to link against gomp via -lgomp (it stand for gnu open mp)

14
Programs / multiple precision division
« on: July 22, 2021, 09:38:05 am »
have a look at Dr. David M. Smith's paper http://dmsmith.lmu.build/MComp1996.pdf
it divides two floating point numbers represented as arrays of double, the decimal point is assumed to be at the left-most position and the first element of the array is the exponent, the second element is the first decimal digit and thereafter the elements hold 4 digits

15
QB64 Discussion / unsolicited password reset?
« on: June 30, 2021, 08:46:41 am »
just received this email
Dear jack,
This mail was sent because the 'forgot password' function has been applied to your account. To set a new password, click the following link:
is it for real or is it phishing?

Pages: [1] 2 3