>> a = 255
a =
255
>> bitset(a,1,0)
ans =
254
here the first bit is set to 0 so we get 11111110 equivalent to 254
>> bitset(a,[1,2],0)
ans =
254 253
here the 1st bit and 2nd bit are being set to 0 seperately. Hence we get
11111110 equivalent to 254
11111101 equivalent to 253
how to get 11111100 equivalent to 252?
Apply bitset twice:
bitset(bitset(a, 1, 0), 2, 0)
The order of application should not matter.
Alternatively, you can use the fact that bitset is an equivalent to applying the correct sequence of bitand, bitor and bitcmp operations.
Since you are interested in turning off multiple bits, you can do
bitand(bitset(a, 1, 0), bitset(a, 2, 0))
Here's a one-liner:
a = 255;
bits = [1,2];
bitand(a,bitcmp(sum(2.^(bits-1)),'uint32'))
Taken apart:
b = sum(2.^(bits-1))
computes the integer with the given bits set. Note that bits must not contain duplicate elements. Use unique to enforce this: bits = unique(bits).
c = bitcmp(b,'uint32')
computes the 32-bit complement of the above. ANDing with the complement resets the given bits.
bitand(a,c)
computes the binary AND of the input number and the integer with the given bits turned off.
Setting bits is easier:
a = 112;
bits = [1,2];
bitor(a,sum(2.^(bits-1)))
Maybe most explicit, easiest to understand, you can convert to a string representing binary and then do the operations there, then convert back.
a = 255
bin_a = flip(dec2bin(a)) % flip to make bigendian
bin_a([1, 2]) = '0'
a = bin2dec(flip(bin_a))
Here is a little recursive function based on the answer from #Mad Physicist that will allow zeroing of any number of bits in data . Thanks for the original info. The recursion is probably dead obvious to most people but it might help somebody out.
function y = zero_nbits(x, n)
y = bitset(x, n, 0)
if n > 1
y = zero_nbits(y, n-1);
end
end
Related
I want to test a piece of function and from 127, it is normal for me that 127+1 = -128. But for Matlab, it saturates my value even though it is a desired behavior on my code.
There are explanations to disable this option on Simulink but what about for a script? I don't know how to disable this feature.
Overflow is not part of Matlab hypotheses.
You need to implement this behaviour in your script using the modulo function (mod).
For example:
>> a=127; mod(a+128,256)-128
ans =
127
>> a=128; mod(a+128,256)-128
ans =
-128
Since you use 127 and -128 as the examples, I assume you are working with int8 variable types. To get the modulo behavior you want, you could use a simple C mex routine to do the arithmetic (since your C compiler will in all likelihood optimize this overflow condition away as simple modulo behavior), or in m-code you can convert to a larger type and do the arithmetic yourself (assumes your machine uses 2's complement storage for integer types). E.g.,
a8 = int8(127); % sample data
b8 = int8(1); % sample data
a16 = int16(a8); % convert to larger type
b16 = int16(b8); % convert to larger type
c16 = a16 + b16 % do the addition in larger type
c16 = int16
128
c8s = typecast(c16,'int8') % typecast back to int8 (assume 2's complement storage)
c8s = 1x2
-128 0
c8 = c8s(1) % pick either c8s(1) or c8s(2) depending on endian of your machine
c8 = int8
-128
If you are working with arrays of numbers instead of scalars, then you could put this in a loop or vectorize the last line as either c8s(1:2:end) or c8s(2:2:end)
You may use fi object from Fixed-Point toolbox and set OverflowAction to Wrap.
Using fi for applying int8 type that overflows, is a bit of an overkill, but possible.
Example:
x = fi(127, true, 8, 0, 'OverflowAction', 'Wrap', 'SumMode', 'SpecifyPrecision', 'SumWordLength', 8, 'SumFractionLength', 0);
x + 1
Output:
ans =
-128
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 8
FractionLength: 0
RoundingMethod: Nearest
OverflowAction: Wrap
ProductMode: FullPrecision
SumMode: SpecifyPrecision
SumWordLength: 8
SumFractionLength: 0
CastBeforeSum: true
If you really want to use the int8 overflow and not simulate it with the mod function, you can use the typecast function.
First, you need to convert your variable into an int (otherwise it is by default a double in Matlab). Then you cast it to an int8 and you keep only the first byte:
>> a=127; getfield(typecast(int64(a),'int8'),{1})
ans =
int8
127
>> a=128; getfield(typecast(int64(a),'int8'),{1})
ans =
int8
-128
I have a problem with the mod function output in Matlab. I am trying to perform some calculations for ECC double and add algorithm. I am reading data from a file and storing it in a variable and then performing some operations. All works smoothly except that I get 0 in temp1 when I use mod(X2,P). However if I put in values stored in X2(3.0323e+153) and P(1.1579e+77) on command window (mod( 3.0323e+153, 1.1579e+77)), I get the correct values. Can anyone please help me? Below is the part of script which is problematic.
P = hex2dec('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F');
line = fread(fileID,[1,67],'*char');
while ~feof(fileID)
PX = line(4:67);
X = hex2dec(PX);
X2 = X^2;
temp1= mod(X2 , P)
end
line = fread(fileID,[1,69],'*char');
end
fclose(fileID);
I think the problem lies with how you're initializing P. From the documentation for hex2dec (emphasis mine):
d = hex2dec('hex_value') converts hex_value to its floating-point integer representation. The argument hex_value is a hexadecimal integer stored as text. If the value of hex_value is greater than the hexadecimal equivalent of the value returned by flintmax, then hex2dec might not return an exact conversion.
And the value of flintmax is:
>> flintmax
ans =
9.007199254740992e+15
Quite a bit smaller than your value for P. In fact, if we use num2hex to look at the two ways you initialize P, you can see a clear difference:
>> P = hex2dec('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F');
>> num2hex(P)
ans =
4ff0000000000000
>> num2hex(1.1579e+77)
ans =
4fefffda293c30de
As it turns out, the inexact conversion done by hex2dec results in a number that evenly divides into 3.0323e+153, thus giving you a remainder of 0:
>> mod(3.0323e+153, P)
ans =
0
>> mod(3.0323e+153, 1.1579e+77)
ans =
8.795697942083107e+76
I want to know if it's possible in MATLAB to discard overflow digits in MATLAB when I add two binary numbers.
I've only been able to find how to have a least number of binary digits, but how to I set a maximum number of digits?
For example:
e = dec2bin(bin2dec('1001') + bin2dec('1000'))
That gave me:
e =
10001
How do I get only '0001'?
dec2bin will always give you the minimum amount of bits to represent a number. If you would like to retain the n least significant digits, you have to index into the string and grab those yourself.
Specifically, if you want to retain only the n least significant digits, given that you have a base-10 number stored in num, you would do this:
out = dec2bin(num);
out = out(end-n+1:end);
Bear in mind that this performs no error checking. Should n be larger than the total number of bits in the string, you will get an out of bounds error. I'm assuming you're smart enough to use this and know what you're doing.
So for your example:
e = dec2bin(bin2dec('1001') + bin2dec('1000'));
n = 4, and so:
>> n = 4;
>> e = e(end-n+1:end)
e =
0001
Here is a more robust (but less efficient, I fear) way: What you describe is exactly the modulo operation. A 4-bit binary number is the remainder after a division by 0b10000 = 16. This can be done using the mod function in MATLAB.
>> e = dec2bin(mod(bin2dec('1001') + bin2dec('1000'),16),4)
e =
0001
Note: I added 4 as additional argument to the dec2bin function, so the output will always be 4-bit wide.
This can of course be generalized to any bit width: If you want to add 8-bit numbers, you will need the remainder of the division by 0b1'0000'0000 = 256, for example
>> e = dec2bin(mod(bin2dec('10011001') + bin2dec('10001000'),256),8)
e =
00100001
Or for shorter numbers, e.g. 2-bit wide, it is 0b100 = 4:
>> e = dec2bin(mod(bin2dec('10') + bin2dec('11'),4),2)
e =
01
So here is what I was trying to do. I'm absolutely new to matlab. It has only been a day or so that I've used it and here is a little something that my teacher had asked me to do. Embed statements or group of strings within an image using the LSB Algorithm. The string is to be read from a file.
As of now, I've not used any file operations. I'm trying this using one character and I don't know whats wrong. The algo seems simple but my output i.e, both the cover and the steg pixels show the same value. :(
cover=imread('D:\l.jpg');
steg=cover;
l=1;
LSB=0;
height = size (cover, 1);
width = size (cover, 2);
message = 'J' ;
mdec = uint8(message);
mbin = dec2bin(mdec, 8);
mbins= mbin(:);
len=length(mbins);
for i = 1:height
for j = 1:width
if(l<=len)
LSB = mod(cover(i,j), 2);
if(mbins(l)==LSB)
steg(i,j) = cover(i,j);
else if (mbins(l)~=LSB && LSB==1 && mbins(l)==0)
steg(i,j) = cover(i,j)-1;
else if (mbins(l)~=LSB && LSB==0 && mbins(l)==1)
steg(i,j) = cover(i,j)+1;
end
end
end
l=l+1;
end
end
end
imwrite(steg,'D:\hidden.jpg');
%imshow(steg)
cover(1, 1:8)
steg(1, 1:8)
Oh, nested loops... that's not the way to go.
You want to replace the least significant bits of the first l pixels with the binary ascii representation of your input string.
First thing that went wrong - converting char to binary:
Converting a character to its binary representation should be done using bitget
>> bitget( uint8('J'), 1:8 )
0 1 0 1 0 0 1 0
Gives back 1-by-8 binary array, while using dec2bin:
>> dec2bin( uint8('J'), 8 )
01001010
Gives back 1-by-8 string: the actual numeric values of this array are
>> uint8(dec2bin( uint8('J'), 8 ))
48 49 48 48 49 48 49 48
Can you appreciate the difference between the two methods?
If you insist on using dec2bin, consider
>> dec2bin( uint8('J'), 8 ) - '0'
0 1 0 0 1 0 1 0
Second point - nested loops:
Matlab favors vector/matrix vectorized operations rather than loops.
Here's a nice way of doing it without loops, assuming cover is a gray scale image (that is it has a single color channel rather than 3) of type uint8.
NoLsb = bitshift( bitshift( cover, -1 ), 1 ); %// use shift operation to set lsb to zero
lsb = cover - NoLsb; %// get the lsb values of ALL pixels
lsb( 1:l ) = mbins; %// set lsb of first l pixels to bits of message
steg = NoLsb + lsb; %// this is it!
I can't get the bit 2 in MatLab
for example:
enter code here
% c is an array to save the get bit result
a is decimal = 253
convert it to binary
a=11111101
k=1;
c(k)=bitget(a,2);
c=0;
what I need is c(1)=0;
You need bin2dec and bitget.
The code, you need to use is bitget(a,2) rather then getbit, and its little endian, so its looking from the right, meaning bit number 2 will return 0
Updating answer to updated question: again, you still need to be using the bitget command,
and it is NOT looking at the bits from the left, it is looking at them from the right.
For example if your bits were a=11110000:
bitget(a,1) = 0
bitget(a,2) = 0
bitget(a,3) = 0
bitget(a,4) = 0
bitget(a,5) = 1
bitget(a,6) = 1
bitget(a,7) = 1
bitget(a,8) = 1
I hope this helps
3rd update:
dec2bin will always return string values unfortunately, so I checked to see, if they output the value in vectors and for that you can use de2bi, so for example then
253 will look like x = [1, 1, 1, 1, 1, 1, 0, 1], and if you want to access a particular location then you can just do x[y] and have your number, I hope this helps.