[dynamic_link] fix ilib_gen_Make_unix regression after fb164e7
[scilab.git] / scilab / modules / elementary_functions / macros / bitcmp.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) ???? - INRIA - Farid BELAHCENE
3 // Copyright (C) 2008 - INRIA - Pierre MARECHAL
4 //
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13
14 function y = bitcmp(x,n)
15
16     // BITCMP function
17     //
18     // Given an unsigned integer x, this function returns the unsigned integer
19     // which is the integer corresponding to the complementary of the binary
20     // form of x
21     //
22     // If the bits number of the x binary representation is less than the
23     // bitmax number (8,16 or 32) then the bits '1' are added to the
24     // complementary in order to have bitmax number (8, 16 or 32) for the
25     // complementary
26     //
27     // for example for the type uint8 (bitmax=8), the complementary of '1101' is not '0010' but '11110010'
28     // The integer n sets the bits max number
29     // -Inputs :
30     //  x : an unsigned integer
31     //  n : a positive integer between 1 and the bitmax of the x type
32     //
33     // -Output :
34     //  y : an unsigned integer
35     //
36     // P. Marechal, 5 Feb 2008
37     //   - Add argument check
38
39     // check number input argument
40     rhs = argn(2);
41
42     if rhs == 0 then
43         error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"),"bitcmp",1));
44     elseif (type(x) == 1) & (rhs == 1) then
45         error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"bitcmp",2));
46     end
47
48     // check type
49
50     if    (type(x)==1  & (x-floor(x)<>0 | x<0)) ..
51         | (type(x)==8  & (inttype(x)<10)) ..
52         | (type(x)<>1  & type(x)<>8) then
53
54         error(msprintf(gettext("%s: Wrong input argument #%d: Scalar/matrix of unsigned integers expected.\n"),"bitcmp",1));
55     end
56
57     if  (rhs == 2) & ( ..
58         (type(n)==1  & (n-floor(n)<>0 | x<0)) ..
59         | (type(n)==8  & (inttype(n)<10)) ..
60         | (type(n)<>1  & type(n)<>8) ..
61         | (size(n,"*")<>1) ) then
62
63         error(msprintf(gettext("%s: Wrong input argument #%d: An unsigned integer expected.\n"),"bitcmp",2));
64     end
65
66     // check n value
67
68     select inttype(x)
69     case 0  then nmax = 52;
70     case 11 then nmax = 8;
71     case 12 then nmax = 16;
72     case 14 then nmax = 32;
73     end
74
75     if rhs>1 then
76
77         if (n>nmax) | (n<1) then
78             error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be between %d and %d.\n"),"bitcmp",2,1,nmax));
79         end
80
81     else
82         n = nmax;
83     end
84
85     // Algorithm
86     // =========================================================================
87
88     // empty matrix shortcut
89
90     if isempty(x) then
91         y = [];
92         return;
93     end
94
95     // unit8, uint16 and uint32 shortcut
96
97     if type(x)==8 then
98         y = ~x;
99         if rhs > 1 then
100             select inttype(x)
101             case 11 then y = y & uint8(  2^n - 1);
102             case 12 then y = y & uint16( 2^n - 1);
103             case 14 then y = y & uint32( 2^n - 1);
104             end
105         end
106         return;
107     end
108
109     n = ones(x)*n;
110
111     if type(x) == 1 then
112
113         a     = 2^32;
114
115         y_LSB = uint32( x - double(uint32(x/a)) * a ); // LSB Less Significant Bits
116         y_MSB = uint32( x/a );                         // MSB Most Significant Bits
117
118         y_LSB = ~y_LSB;
119         y_MSB = ~y_MSB;
120
121         if n <= 32 then
122             y_LSB = y_LSB & uint32( 2^n - 1);
123             y_MSB = uint32(0);
124         else
125             y_MSB = y_MSB & uint32( 2^(n-32) - 1);
126         end
127
128         y = double( a * y_MSB + y_LSB );
129     end
130
131 endfunction