]> www.ginac.de Git - cln.git/blob - src/float/lfloat/misc/cl_LF_leninc.cc
34c35799293cd4bcefa02a5b2ed7e45b20a1794b
[cln.git] / src / float / lfloat / misc / cl_LF_leninc.cc
1 // cl_LF_len_incsqrt().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_LF.h"
8
9
10 // Implementation.
11
12 uintC cl_LF_len_incsqrt (uintC n)
13 {
14 // Methode bei intDsize=16:
15 // n -> n+1 für n<=12 wegen 16n+sqrt(16n)+2 < 16(n+1)
16 // n -> n+2 für n<=56 wegen 16n+sqrt(16n)+2 < 16(n+2)
17 // n -> n+4 für n<=240
18 // n -> n+8 für n<=992
19 // n -> n+16 für n<=4032
20 // n -> n+32 für n<=16256
21 // n -> n+65 für n<=65535
22 // Allgemein: intDsize*n + sqrt(intDsize*n) + 2 < intDsize*(n+inc)
23 // <==>       sqrt(intDsize*n) + 2 < intDsize*inc
24 // <==>       sqrt(intDsize*n) < intDsize*inc - 2
25 // <==>       intDsize*n < intDsize^2*inc^2 - 4*intDsize*inc + 4
26 // <==>       n <= intDsize*inc^2 - 4*inc
27         return
28           #define NMAX(k)  (uintL)((intDsize*(k)-4)*(k))
29           #define FITS(n,k)  ((n) <= NMAX(k))
30           #define n_max  (uintL)(bitm(intCsize)-1)
31           #define TRYINC(inc)  FITS(n_max,inc) || FITS(n,inc) ? RETINC(inc) :
32           #define RETINC(inc)  \
33             /* at this point we know  n <= NMAX(inc) */                 \
34             /* Check whether n + (inc) overflows. */                    \
35           ((NMAX(inc) <= n_max-(inc)) || (n <= n_max-(inc)) ? n+(inc) : n_max)
36           #define TEST(i)  TRYINC(1UL<<i)
37           TEST(0)
38           TEST(1)
39           TEST(2)
40           TEST(3)
41           TEST(4)
42           TEST(5)
43           TEST(6)
44           TEST(7)
45           TEST(8)
46           TEST(9)
47           TEST(10)
48           TEST(11)
49           TEST(12)
50           TEST(13)
51           // No TEST(14), because NMAX(1UL<<14) is already out of range.
52           n_max;
53 }