2 #include "mp-internal.h"
3 #include "calctool.h" // FIXME: Used for MAX_DIGITS
5 static char digits
[] = "0123456789ABCDEF";
7 static int hex_to_int(char digit
)
9 if (digit
>= '0' && digit
<= '9')
11 if (digit
>= 'A' && digit
<= 'F')
12 return digit
- 'A' + 10;
13 if (digit
>= 'a' && digit
<= 'f')
14 return digit
- 'a' + 10;
20 mp_bitwise(const MPNumber
*x
, const MPNumber
*y
, int (*bitwise_operator
)(int, int), MPNumber
*z
, int wordlen
)
22 char text1
[MAX_DIGITS
], text2
[MAX_DIGITS
], text_out
[MAX_DIGITS
];
23 int offset1
, offset2
, offset_out
;
25 mp_cast_to_string(x
, 16, 0, 0, text1
, MAX_DIGITS
);
26 mp_cast_to_string(y
, 16, 0, 0, text2
, MAX_DIGITS
);
27 offset1
= strlen(text1
) - 1;
28 offset2
= strlen(text2
) - 1;
29 offset_out
= wordlen
/ 4 - 1;
30 if (offset_out
<= 0) {
31 offset_out
= offset1
> offset2
? offset1
: offset2
;
33 if (offset_out
> 0 && (offset_out
< offset1
|| offset_out
< offset2
)) {
34 mperr("Overflow. Try a bigger word size");
38 /* Perform bitwise operator on each character from right to left */
39 for (text_out
[offset_out
+1] = '\0'; offset_out
>= 0; offset_out
--) {
43 v1
= hex_to_int(text1
[offset1
]);
47 v2
= hex_to_int(text2
[offset2
]);
50 text_out
[offset_out
] = digits
[bitwise_operator(v1
, v2
)];
53 mp_set_from_string(text_out
, 16, z
);
57 static int mp_bitwise_and(int v1
, int v2
) { return v1
& v2
; }
58 static int mp_bitwise_or(int v1
, int v2
) { return v1
| v2
; }
59 static int mp_bitwise_xor(int v1
, int v2
) { return v1
^ v2
; }
60 static int mp_bitwise_xnor(int v1
, int v2
) { return v1
^ v2
^ 0xF; }
61 static int mp_bitwise_not(int v1
, int dummy
) { return v1
^ 0xF; }
65 mp_is_overflow (const MPNumber
*x
, int wordlen
)
68 mp_set_from_integer(2, &tmp1
);
69 mp_pwr_integer(&tmp1
, wordlen
, &tmp2
);
70 return mp_is_greater_than (&tmp2
, x
);
75 mp_and(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
)
77 mp_bitwise(x
, y
, mp_bitwise_and
, z
, 0);
82 mp_or(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
)
84 mp_bitwise(x
, y
, mp_bitwise_or
, z
, 0);
89 mp_xor(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
)
91 mp_bitwise(x
, y
, mp_bitwise_xor
, z
, 0);
96 mp_xnor(const MPNumber
*x
, const MPNumber
*y
, int wordlen
, MPNumber
*z
)
98 mp_bitwise(x
, y
, mp_bitwise_xnor
, z
, wordlen
);
103 mp_not(const MPNumber
*x
, int wordlen
, MPNumber
*z
)
106 mp_set_from_integer(0, &temp
);
107 mp_bitwise(x
, &temp
, mp_bitwise_not
, z
, wordlen
);
112 mp_mask(const MPNumber
*x
, int wordlen
, MPNumber
*z
)
114 char text
[MAX_DIGITS
];
117 /* Convert to a hexadecimal string and use last characters */
118 mp_cast_to_string(x
, 16, 0, 0, text
, MAX_DIGITS
);
120 offset
= wordlen
/ 4;
121 offset
= len
> offset
? len
- offset
: 0;
122 mp_set_from_string(text
+ offset
, 16, z
);
127 mp_shift(const MPNumber
*x
, int count
, MPNumber
*z
)
129 int i
, multiplier
= 1;
132 for (i
= 0; i
< count
; i
++)
134 mp_multiply_integer(x
, multiplier
, z
);
138 for (i
= 0; i
< -count
; i
++)
140 mp_divide_integer(x
, multiplier
, &temp
);
141 mp_integer_component(&temp
, z
);
147 mp_1s_complement(const MPNumber
*x
, int wordlen
, MPNumber
*z
)
150 mp_set_from_integer(0, &t
);
151 mp_bitwise(x
, &t
, mp_bitwise_xnor
, z
, wordlen
);
156 mp_2s_complement(const MPNumber
*x
, int wordlen
, MPNumber
*z
)
158 mp_1s_complement (x
, wordlen
, z
);
159 mp_add_integer (z
, 1, z
);