~ubuntu-branches/ubuntu/lucid/gcalctool/lucid-updates

« back to all changes in this revision

Viewing changes to src/mp-binary.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2010-04-07 19:41:56 UTC
  • mfrom: (1.3.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100407194156-hgj8g002ffce2de0
Tags: 5.30.0.is.5.28.2-0ubuntu1
Downgrade to 5.28.2 as the new version does not support number bases
as well.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
2
 
 *  Copyright (c) 2008-2009 Robert Ancell
3
 
 *
4
 
 *  This program is free software; you can redistribute it and/or modify
5
 
 *  it under the terms of the GNU General Public License as published by
6
 
 *  the Free Software Foundation; either version 2, or (at your option)
7
 
 *  any later version.
8
 
 *
9
 
 *  This program is distributed in the hope that it will be useful, but
10
 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
 
 *  General Public License for more details.
13
 
 *
14
 
 *  You should have received a copy of the GNU General Public License
15
 
 *  along with this program; if not, write to the Free Software
16
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
 
 *  02111-1307, USA.
18
 
 */
19
 
 
20
 
#include <stdio.h>
21
 
 
22
1
#include "mp.h"
23
2
#include "mp-internal.h"
24
3
 
42
21
static void
43
22
mp_bitwise(const MPNumber *x, const MPNumber *y, int (*bitwise_operator)(int, int), MPNumber *z, int wordlen)
44
23
{
45
 
    char text1[MAX_DIGITS], text2[MAX_DIGITS], text_out[MAX_DIGITS], text_out2[MAX_DIGITS];
 
24
    char text1[MAX_DIGITS], text2[MAX_DIGITS], text_out[MAX_DIGITS];
46
25
    int offset1, offset2, offset_out;
47
 
 
 
26
   
48
27
    mp_cast_to_string(x, 16, 0, 0, text1, MAX_DIGITS);
49
28
    mp_cast_to_string(y, 16, 0, 0, text2, MAX_DIGITS);
50
 
    offset1 = strlen(text1) - 1 - strlen("₁₆");
51
 
    offset2 = strlen(text2) - 1 - strlen("₁₆");
 
29
    offset1 = strlen(text1) - 1;
 
30
    offset2 = strlen(text2) - 1;
52
31
    offset_out = wordlen / 4 - 1;
53
32
    if (offset_out <= 0) {
54
33
        offset_out = offset1 > offset2 ? offset1 : offset2;
57
36
        mperr("Overflow. Try a bigger word size");
58
37
        return;
59
38
    }
60
 
 
 
39
   
61
40
    /* Perform bitwise operator on each character from right to left */
62
41
    for (text_out[offset_out+1] = '\0'; offset_out >= 0; offset_out--) {
63
42
        int v1 = 0, v2 = 0;
64
 
 
 
43
        
65
44
        if (offset1 >= 0) {
66
45
            v1 = hex_to_int(text1[offset1]);
67
46
            offset1--;
72
51
        }
73
52
        text_out[offset_out] = digits[bitwise_operator(v1, v2)];
74
53
    }
75
 
 
76
 
    snprintf(text_out2, MAX_DIGITS, "%s₁₆", text_out);
77
 
    mp_set_from_string(text_out2, z);
 
54
   
 
55
    mp_set_from_string(text_out, 16, z);
78
56
}
79
57
 
80
58
 
81
59
static int mp_bitwise_and(int v1, int v2) { return v1 & v2; }
82
60
static int mp_bitwise_or(int v1, int v2) { return v1 | v2; }
83
61
static int mp_bitwise_xor(int v1, int v2) { return v1 ^ v2; }
 
62
static int mp_bitwise_xnor(int v1, int v2) { return v1 ^ v2 ^ 0xF; }
84
63
static int mp_bitwise_not(int v1, int dummy) { return v1 ^ 0xF; }
85
64
 
86
65
 
87
 
bool
 
66
int
88
67
mp_is_overflow (const MPNumber *x, int wordlen)
89
68
{
90
69
    MPNumber tmp1, tmp2;
97
76
void
98
77
mp_and(const MPNumber *x, const MPNumber *y, MPNumber *z)
99
78
{
100
 
    if (!mp_is_positive_integer(x) || !mp_is_positive_integer(y))
101
 
    {
102
 
        /* Translators: Error displayed when boolean AND attempted on non-integer values */
103
 
        mperr(_("Boolean AND is only defined for positive integers"));
104
 
    }
105
 
 
106
79
    mp_bitwise(x, y, mp_bitwise_and, z, 0);
107
80
}
108
81
 
110
83
void
111
84
mp_or(const MPNumber *x, const MPNumber *y, MPNumber *z)
112
85
{
113
 
    if (!mp_is_positive_integer(x) || !mp_is_positive_integer(y))
114
 
    {
115
 
        /* Translators: Error displayed when boolean OR attempted on non-integer values */
116
 
        mperr(_("Boolean OR is only defined for positive integers"));
117
 
    }
118
 
 
119
86
    mp_bitwise(x, y, mp_bitwise_or, z, 0);
120
87
}
121
88
 
123
90
void
124
91
mp_xor(const MPNumber *x, const MPNumber *y, MPNumber *z)
125
92
{
126
 
    if (!mp_is_positive_integer(x) || !mp_is_positive_integer(y))
127
 
    {
128
 
        /* Translators: Error displayed when boolean XOR attempted on non-integer values */
129
 
        mperr(_("Boolean XOR is only defined for positive integers"));
130
 
    }
131
 
 
132
93
    mp_bitwise(x, y, mp_bitwise_xor, z, 0);
133
94
}
134
95
 
135
96
 
136
97
void
 
98
mp_xnor(const MPNumber *x, const MPNumber *y, int wordlen, MPNumber *z)
 
99
{
 
100
    mp_bitwise(x, y, mp_bitwise_xnor, z, wordlen);
 
101
}
 
102
 
 
103
 
 
104
void
137
105
mp_not(const MPNumber *x, int wordlen, MPNumber *z)
138
106
{
139
107
    MPNumber temp;
140
 
 
141
 
    if (!mp_is_positive_integer(x))
142
 
    {
143
 
        /* Translators: Error displayed when boolean XOR attempted on non-integer values */
144
 
        mperr(_("Boolean NOT is only defined for positive integers"));
145
 
    }
146
 
 
147
108
    mp_set_from_integer(0, &temp);
148
109
    mp_bitwise(x, &temp, mp_bitwise_not, z, wordlen);
149
110
}
154
115
{
155
116
    char text[MAX_DIGITS];
156
117
    size_t len, offset;
157
 
 
 
118
    
158
119
    /* Convert to a hexadecimal string and use last characters */
159
120
    mp_cast_to_string(x, 16, 0, 0, text, MAX_DIGITS);
160
 
    len = strlen(text) - strlen("₁₆");
 
121
    len = strlen(text);
161
122
    offset = wordlen / 4;
162
123
    offset = len > offset ? len - offset: 0;
163
 
    mp_set_from_string(text + offset, z);
 
124
    mp_set_from_string(text + offset, 16, z);
164
125
}
165
126
 
166
127
 
168
129
mp_shift(const MPNumber *x, int count, MPNumber *z)
169
130
{
170
131
    int i, multiplier = 1;
171
 
 
172
 
    if (!mp_is_integer(x)) {
173
 
        /* Translators: Error displayed when bit shift attempted on non-integer values */
174
 
        mperr(_("Shift is only possible on integer values"));
175
 
        return;
176
 
    }
177
 
 
 
132
    
178
133
    if (count >= 0) {
179
134
        for (i = 0; i < count; i++)
180
135
            multiplier *= 2;
195
150
{
196
151
    MPNumber t;
197
152
    mp_set_from_integer(0, &t);
198
 
    mp_bitwise(x, &t, mp_bitwise_xor, z, wordlen);
199
 
    mp_not(z, wordlen, z);
 
153
    mp_bitwise(x, &t, mp_bitwise_xnor, z, wordlen);
200
154
}
201
155
 
202
156