How to do bit-wise operations on symbolic variables that may be very long possibly larger than inter 64

2 vues (au cours des 30 derniers jours)
Below is something I was able to do with some smaller numbers in base 2 and I can do base 10 also. Using Min,Max I can do AND and OR but I haven't been able to understand the use of the Symbolic Tool Box to do this symbolically .
a=12345
b=9867
c=0
n=0
while a>0 |b>0
digita=mod(a,2)
digitb=mod(b,2)
c=c+max(digita,digitb)*2^n
n=n+1
a=floor(a/2)
b=floor(b/2)
end
c

Réponse acceptée

John D'Errico
John D'Errico le 27 Jan 2024
Modifié(e) : John D'Errico le 28 Jan 2024
Why is there a problem? Just define the numbers as syms. Make sure that you don't make the mistake of computing 2^n as a DOUBLE. That would surely cause failure at some point if n grows large enough.
a = sym('1234566726356446657575412365654161131310325345345');
b = sym('9866848646846846864684635468141413513513511534146867');
c = sym(0);
n=0;
while a>0 || b>0
digita=mod(a,2);
digitb=mod(b,2);
c=c+max(digita,digitb)*sym(2)^n;
n=n+1;
a=floor(a/2);
b=floor(b/2);
end
n
n = 173
c
c = 
9868036217465768677971888683212354493291227772861811
a
a = 
0
b
b = 
0
Make sure you keep everything a sym, and you will have no problem. Note my use of the || operator in the while statement. It is not really that significant here, but it can improve the speed of your code.
However, did you really need to use a loop there? Of course not.
a = sym('1234566726356446657575412365654161131310325345345');
b = sym('9866848646846846864684635468141413513513511534146867');
% in case we need leading zero bits on the smaller number
% I could also pad the smaller, but this test is trivial.
if a > b
abin = dec2bin(a);
bbin = dec2bin(b,numel(abin));
else
bbin = dec2bin(b);
abin = dec2bin(a,numel(bbin));
end
abin
abin = '00000000000001101100000111111111000101111101101011100111010000101000000111111100011110010100001100111001010110101111100100010110110000011110100110001101110101010110001000001'
bbin
bbin = '11010010111110010101111111011011010001101111110000000000111110010010000110110110100111011111110001011110000110111011001010100010101101010001011100000110011110011010100110011'
% I could compute c here in many ways, but bin2dec does
% not generate a sym. In my large integer codes, I provided
% that as an option, but not hard to do.
cbin = abin;
cbin(bbin == '1') = '1';
nc = numel(cbin);
c = dot(cbin - '0',sym(2).^(nc-1:-1:0))
c = 
9868036217465768677971888683212354493291227772861811
Note that c is the same in both cases, but that a loop was never necessary.
Ok, could we have used direct bit operators here? For example, we can do this:
a = 12345;
b = 9867;
bitor(a,b)
ans = 14011
The problem is, bitor does not apply to symbolic numbers. Sorry.
  1 commentaire
Steve
Steve le 28 Jan 2024
Thanks very much for the explaination on that and for the example. I learned something new for which I am gratefull

Connectez-vous pour commenter.

Plus de réponses (2)

Walter Roberson
Walter Roberson le 27 Jan 2024
Modifié(e) : Walter Roberson le 28 Jan 2024
a = sym(12345);
b = sym(9867);
c = sym(0);
n = sym(0);
while a>0 |b>0
digita=mod(a,2);
digitb=mod(b,2);
c=c+max(digita,digitb)*2^n;
n=n+1;
a=floor(a/2);
b=floor(b/2);
end
c
c = 
14011
n
n = 
14

Sulaymon Eshkabilov
Sulaymon Eshkabilov le 27 Jan 2024
Is this what you are trying to get:
syms a b c n % Create symbols
a = 12345;
b = 9867;
c = sym(0);
n = 0;
while a > 0 || b > 0
digita = mod(a, 2);
digitb = mod(b, 2);
c = c + max(digita, digitb) * 2^n;
n = n + 1;
a = floor(a / 2);
b = floor(b / 2);
end
disp(c);
14011
  6 commentaires
John D'Errico
John D'Errico le 27 Jan 2024
Um, predefining those variables as syms does NOTHING.
syms a b c n % Create symbols
a = 12345;
b = 9867;
whos a b
Name Size Bytes Class Attributes a 1x1 8 double b 1x1 8 double
Do you see that now, a and b are DOUBLES?
Sulaymon Eshkabilov
Sulaymon Eshkabilov le 28 Jan 2024
Yes, I overlooked. This is what it should be like:
a = sym(12345);
b = sym(9867);
c = sym(0);
n = sym(0);
while a > 0 || b > 0
digita = mod(a, 2);
digitb = mod(b, 2);
c = c + max(digita, digitb) * 2^n;
n = n + 1;
a = floor(a / 2);
b = floor(b / 2);
end
disp(c);
14011
whos a b c n
Name Size Bytes Class Attributes a 1x1 8 sym b 1x1 8 sym c 1x1 8 sym n 1x1 8 sym

Connectez-vous pour commenter.

Produits


Version

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by