bitget(u-int64) fixed & examples added
[scilab.git] / scilab / modules / elementary_functions / tests / unit_tests / bitget.tst
1 // ===================================================================
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2008 - INRIA - Pierre MARECHAL <pierre.marechal@inria.fr>
4 // Copyright (C) 2017 - Samuel GOUGEON
5 //
6 //  This file is distributed under the same license as the Scilab package.
7 // ===================================================================
8
9 // <-- CLI SHELL MODE -->
10 // <-- NO CHECK REF -->
11
12 // Test 1
13 // ===================================================================
14 // Test 1.1
15 A = floor(2^52 * rand(20,20));
16 for i=1:size(A,"*");
17     B = strcat(string(bitget(A(i), 1:52)));
18     C = strrev(dec2bin(A(i),52));
19     assert_checkequal(B, C);
20 end
21
22 // Test 1.2
23 for i = [1 2 4 8 11 12 14 18]               // Loop on int types
24     m = 8 * modulo(i,10) - 1 + 1*(i>10);    // Maximal bit rank
25     m = min(m, 52);   // due to dec2base() limitation to 2^52
26     A = iconvert(floor( 2^m * rand(20,20)), i);
27     for k = 1:size(A,"*");
28         B = strcat(string(bitget(A(k), 1:m)));
29         C = strrev(dec2bin(A(k), m));
30         assert_checkequal(B, C);
31     end
32 end
33
34 // Test 2
35 // ===================================================================
36 A0 = bin2dec(["0001" "0010";"0011" "0100"]);
37 B =         [    1      0 ;    1      0 ];
38 C =         [   0      1  ;   1      0  ];
39 for i = [0 1 2 4 8 11 12 14 18]
40     A = iconvert(A0,i);
41     assert_checktrue(and( bitget(A,1)==B));
42     assert_checktrue(and( bitget(A,2)==C));
43 end
44
45 // Test 3: about bitmax
46 // ===================================================================
47 k = [0 1 2 4 8 11 12 14 18];
48 bitmax = [1024 7 15 31 63 8 16 32 64];
49 for i = 1:length(k)
50     n = iconvert(123, k(i));
51     assert_checkequal(execstr("bitget(n, bitmax(i));","errcatch"), 0);
52     assert_checkfalse(execstr("bitget(n, bitmax(i)+1);" ,"errcatch")==0);
53     assert_checkfalse(execstr("bitget(n, 0);" ,"errcatch")==0);
54 end
55
56 // Tests about input / output types
57 // ===================================================================
58 it = [0 1 2 4 8 11 12 14 18];
59 for i = it
60     n = abs(iconvert([1 10 100 271 1000 3467 34567], i));
61     for j = it
62         r = bitget(n, iconvert([1:7], j));
63         assert_checkequal(inttype(r), i);
64     end
65 end
66
67 // Tests about input / output sizes
68 // ===================================================================
69 b = [1 3 4 6 7];
70 n = sum(2^(b-1));
71
72 // x scalar, pos matrix:
73 r = bitget(n, [1 2 3 ; 5 6 7]);
74 assert_checkequal(size(r), [2 3]);
75 assert_checkequal(r, [1 0 1 ; 0 1 1]);
76
77 // x matrix, pos scalar:
78 r = bitget(n*[1 2 4 ; 8 16 32]', 6);
79 assert_checkequal(size(r), [3 2]);
80 assert_checkequal(r, [1 0 1 ; 1 0 1]');
81
82 // x and pos matrices of identical sizes
83 x = cumsum(2^(b-1));
84 x = [x ; x];        // 2x5
85 pos = [1 3 5 7 9 ; 8 6 4 2 1];
86 r = bitget(x, pos);
87 assert_checkequal(size(r), [2 5]);
88 assert_checkequal(r, [1 1 0 0 0 ; 0 0 1 0 1]);
89
90 // x and pos are arrays with mismatching sizes
91 x = [39  8  4  44  52  5  6  14  64 39  12  4  62  29  12  50  39  29];
92 x = matrix(x,2,3,3);
93 //(:,:,1)
94 //   39.   4.    52.
95 //   8.    44.   5.
96 //(:,:,2)
97 //   6.    64.   12.
98 //   14.   39.   4.
99 //(:,:,3)
100 //   62.   12.   39.
101 //   29.   50.   29.
102 x = sum(2.^(x-1),3);
103 ref = [
104   %nan   %nan  0.   1.
105    0.    1.    0.   0.
106    %nan  %nan  1.   0.
107    0.    0.    0.   1.
108    0.    0.    1.   1.
109    1.    0.    0.   0.
110 ];
111 assert_checkequal(bitget(x, [5 8 12 39]), ref);
112
113 // Bits extraction from decimal numbers > 2^52
114 // ===================================================================
115 assert_checkequal(execstr("bitget(123 , 54);","errcatch"), 0);
116 assert_checkequal(execstr("bitget(123 , 1000);","errcatch"), 0);
117
118 // The extracted values of lower bits below %eps must all be %nan:
119 assert_checktrue(and(isnan(bitget(2^70 , 1:17))));
120 assert_checkequal(bitget(1+2.^[51 53 ; 54 5], [2 1 ; 2 1]), [0 %nan ; %nan 1]);
121
122 // We build a random integer with known bits #0-99
123 // Beware of the bug http://bugzilla.scilab.org/15276
124 i = matrix(1:100, 10, 10);
125 bv = grand(10, 10, "uin", 0, 1)  // Bits values
126 bp = bv.*(i-1);                  // Related powers
127 v = sum(2 .^bp);
128 // We now extract all its bits with bitget()
129 bg = bitget(v, i);
130 // We select extracted bits that have a known value
131 s = ~isnan(bg);
132 // We built the related number. Lower bits are ignored:
133 va = sum(2 .^(bg(s).*(i(s)-1)));
134 // Is it equal to v?  Yes: bitget() works like a charm on huge decimal numbers!
135 assert_checkequal(va, v);
136
137
138 // Big int64 and uint64 integers > 2^53
139 // ===================================================================
140 // uint64
141 // ------
142 // x scalar, all bits
143 for i = 1:5
144     bref = find(grand(1, 64, "uin", 0, 1))';
145     x = bitset(uint64(0), bref);
146     b = bitget(x, 1:64);
147     assert_checkequal(find(b)', bref);
148     assert_checkequal(inttype(b), inttype(x));
149 end
150 // x column, bits 1:64
151 n = 20;
152 bref = grand(n, 64, "uin", 0, 1);
153 bin = bref .* (ones(n, 1) * (1:64));
154 x = [];
155 for i = 1:n
156     x = [ x ; bitset(uint64(0), find(bin(i,:))) ];
157 end
158 assert_checkequal(bitget(x, 1:64), uint64(bref));
159 // Element-wise extraction
160 for i = 1:64
161     assert_checkequal(bitget(x, i*ones(n,1)), uint64(bref(:,i)));
162 end
163
164 // int64
165 // -----
166 for i = 1:5
167     bref = find(grand(1, 63, "uin", 0, 1))';
168     x = bitset(int64(0), bref);
169     b = bitget(x, 1:63);
170     assert_checkequal(find(b)', bref);
171     assert_checkequal(inttype(b), inttype(x));
172 end
173 // x column, bits 1:64
174 n = 20;
175 bref = grand(n,63, "uin", 0, 1);
176 bin = bref .* (ones(n,1)*(1:63));
177 x = [];
178 for i = 1:n
179     x = [x ; bitset(int64(0), find(bin(i,:)))];
180 end
181 assert_checkequal(bitget(x,1:63), int64(bref));
182 // Element-wise extraction
183 for i = 1:63
184     assert_checkequal(bitget(x,i*ones(n,1)), int64(bref(:,i)));
185 end