How can I write the Twos complement and return a hex string ?

Ex:
E5
+
83
=
8E
I k
% ~add 1 to bin_int
*****************************************
Thank you.

8 件のコメント

Irwin2020
Irwin2020 2018 年 10 月 23 日
any help????
James Tursa
James Tursa 2018 年 10 月 23 日
編集済み: James Tursa 2018 年 10 月 23 日
When you say the "strings are any length >= 1" does that mean the strings could be hundreds of digits long? Or is there in fact a practical limit like 8 or 16? Because if it is the latter, then you can simply sign extend and convert to integers and let MATLAB do the calculations for you since MATLAB uses 2's complement for integer storage (on all machines it currently runs on?).
Irwin2020
Irwin2020 2018 年 10 月 24 日
16 digits its fine.
Irwin2020
Irwin2020 2018 年 10 月 24 日
I don't mid if you use the built-in functions such as hex2bin. hex2dec, dec2hex...I believe you will need (for loop) to do the 2's complement as well. all I need is a function could sum 2 hex strings and output 2 Hex Digit and a Decimal Values = (String)
Guillaume
Guillaume 2018 年 10 月 24 日
It makes no sense to say that hex values are signed if you don't specify the number of bits used (or which bit is the sign bit).
The signed 8-bit value A0 is -96, the signed 16-bit value A0 is 160.
Other than that issue, if you're limiting yourself to a maximum of 16 hex digits (thus 64 bits), then as James said, you can simply convert to integer and let matlab do the addition. Note that for 64 bits integer you cannot use hex2dec for the conversion.
Guillaume
Guillaume 2018 年 10 月 25 日
編集済み: Guillaume 2018 年 10 月 25 日
You will have to explain your maths.
  • EF as a signed 8-bit integer is -17
  • 83 as a signed 8-bit integer is -125
  • -17 + -125 is -142 which can't be represented as an 8-bit integer
  • 8E as a signed 8-bit integer is -114
How do you go from -142 to -114?
Guillaume
Guillaume 2018 年 10 月 25 日
And as I said, -142 is not representable as 8-bit integer. So what should the answer be? Matlab answer would be -128, for a C program this would be undefined and could result in anything although some implementations may return +114.
madhan ravi
madhan ravi 2018 年 11 月 20 日
If you close the question that have answers you will unlikely receive any help further plus it ignores the efforts of the answerers

サインインしてコメントする。

 採用された回答

Guillaume
Guillaume 2018 年 10 月 25 日

3 投票

There's a reason I ask all these questions. I don't believe you've thought properly about what it is you're asking. As I keep saying repeatedly saying a number is signed is meaningless if you don't specify how many bits. '8E' represents a negative number on 8-bit. It represents a positive number on 9-bits or more. And it's not a valid number on less than 8-bit.
Anyway, 2-complement addition of hexadecimal numbers:
  • Adding two signed 8-bit integers given in hexadecimal representation and returning the hexadecimal representation of the signed 8-bit sum:
hex1 = 'AA';
hex2 = '2F';
signeddec1 = typecast(uint8(hex2dec(hex1)), 'int8');
signeddec2 = typecast(uint8(hex2dec(hex2)), 'int8');
result = dec2hex(typecast(signeddec1 + signeddec2, 'uint8'))
Of course, since we're working with 8 bits, hexadecimal with more than 2 digits makes no sense and will be interpreted as 'FF'. Also, since we're working with signed 8 bit, any sum below -128 or +127 makes no sense and will result in -128 or +127.
  • Adding two signed 16-bit integers given in hexadecimal representation and returning the hexadecimal representation of the signed 16-bit sum:
hex1 = 'AA10';
hex2 = '2FDE';
signeddec1 = typecast(uint16(hex2dec(hex1)), 'int16');
signeddec2 = typecast(uint16(hex2dec(hex2)), 'int16');
result = dec2hex(typecast(signeddec1 + signeddec2, 'uint16'))
Of course, since we're now working with 16 bits, hexadecimal with more than 4 digits makes no sense and will be interpreted as 'FFFF'. Also, since we're working with signed 16-bit, '8E' is not a negative value. Negative values start at '7FFF'. And since we're working with signed 8 bit, any sum below -32768 or +32767 makes no sense and will result in -32768 or +32767.
  • Adding two signed 32-bit integers given in hexadecimal representation and returning the hexadecimal representation of the signed 32-bit sum:
hex1 = 'AA10EFDE';
hex2 = '2FDE01CB';
signeddec1 = typecast(uint32(hex2dec(hex1)), 'int32');
signeddec2 = typecast(uint32(hex2dec(hex2)), 'int32');
result = dec2hex(typecast(signeddec1 + signeddec2, 'uint32'))
Same comments apply, except now the maximum is 8 hexadecimal digits and the bounds are -2147483648 to +2147483647.
  • For signed 64-bit integers, equivalent to 16 hexadecimal digits, you can no longer use hex2dec as numbers may fall outside the range that it can safely convert (anything greater than hex '20000000000000'). There are slightly more complicated ways to reliably parse the hexadecimal however (with sscanf for example).

1 件のコメント

James Tursa
James Tursa 2018 年 10 月 29 日
"... regardless to their lengths ..."
You are required to use for-loops for this assignment?

サインインしてコメントする。

その他の回答 (2 件)

James Tursa
James Tursa 2018 年 10 月 29 日
編集済み: James Tursa 2018 年 10 月 29 日

1 投票

If you really have to write a for-loop for this, a simple algorithm for adding two 2's complement signed integers represented as hex strings is:
1) Convert each hex string to binary strings of the appropriate length (based on location of sign bit)
2) Add up the bits in the usual fashion ignoring overflow (e.g., grade school arithmetic using a carry bit. SEE NOTE!)
3) Look for overflow (both operands are the same sign but result is opposite sign)
4) Convert the result binary string back into hex
NOTE: You don't have to do anything special for step 2 regarding the signs of the operands. You just add up the bits (including the "sign" bit) like normal grade school arithmetic. If the carry bit overflows past the sign bit in this process you simply ignore it. Doing it this way, the bits of the answer will be correct regardless of the signs of the operands ... just make sure you treat the sign bit just like any other bit in this adding process. Then all you need is the simple check for overflow by examining the signs of the operands and the sign of the result. Of course, you may simply choose to ignore any actual overflow and let the result wrap around like many C/C++ compilers do.

12 件のコメント

Guillaume
Guillaume 2018 年 10 月 30 日
Step 1 can be achieved with:
reshape(dec2bin(sscanf(yourhexadecimalstring, '%1x'), 4)' - '0', 1, [])
For step 3, it is critical to know which bit is the sign bit. The sign bit cannot move around.
let the result wrap around like many C/C++ compilers do
This is the behaviour defined by the C and C++ standard for unsigned integers, and the compiler must implement it.
For signed integers, the behaviour of overflow is undefined. The compiler is free to do whatever it wants, it doesn't even have to be consistent. It can wrap around like for unsigned, it can issue a compiler error (better) or it can start World War 3.
James Tursa
James Tursa 2018 年 10 月 30 日
"... For step 3, it is critical to know which bit is the sign bit. The sign bit cannot move around ..."
Good point. The algorithm assumes that both hex strings have the sign bit in the same spot. If not, then you would have to convert the shorter one to the longer one first.
James Tursa
James Tursa 2018 年 10 月 30 日
"... or it can start World War 3 ..."
Or become self-aware and start building Terminators. Maybe this is how it all started ...
Irwin2020
Irwin2020 2018 年 11 月 1 日
That's sounds ok, but I have already found a way to do the calculations without going through (World War 3...). I have came to conclusion that, if I'm able to brake down the hex string by applying (extractAfter or extractBetween functions into 2 chars' ) regardless to it length, and doing so... I was able to extract the last two strings of (hex1 and hex2) and add them up while setting up 'carry = 0' through 'if' statement, now by doing that..I will get a hex string of 2 char without a carry ( after I have added the first two char from each string). now, the question is how can I create a for loop that's sums the new result/s ( .. result1 + result2+ result3....and so on so fourth ) and returns a hex string? also a for loop for the extractAfter / extractBetween functions? Ex: h1=extractBetween(hex1,length(hex1)-i-1,length(hex1)-i)
Thansks
James Tursa
James Tursa 2018 年 11 月 1 日
編集済み: James Tursa 2018 年 11 月 1 日
You will need to show us your code, not just a description of your code. I don't see how you can do this without implementing a carry bit in some form, regardless of whether you are doing the adding in hex or binary or decimal.
Irwin2020
Irwin2020 2018 年 11 月 1 日
hex1 = 'AA10EFDE';
hex2 = '2FDE01CB';
signeddec1 = typecast(uint32(hex2dec(h1)), 'int32');
signeddec2 = typecast(uint32(hex2dec(h2)), 'int32');
h1=extractAfter(hex1,length(hex1)-2)
h1 = 'DE'
h2=extractAfter(hex2,length(hex2)-2);
h2 = 'CB'
if length(result1) > 2
carry1 = 1
else
carry = 0
end
result = dec2hex(typecast(signeddec1 + signeddec2, 'uint32');
result = '1A9'
carry1 = 1
*** you can also use this shortcut to get the same result when adding***
%result1 = dec2hex(typecast(typecast(uint32(hex2dec(h1)), 'int32') + typecast(uint32(hex2dec(h2))+ carry, 'int32'), 'uint32'));
my problem is with creating a for loop (i)
%h1=extractAfter(hex1,length(hex1)-i-1,length(hex1)-i);
%h2=extractAfter(hex2,length(hex2)-i-1,length(hex2)-i);
and if I could write a for loop to extract the first two hex characters from the first string(hex1) and do the same to the second string(hex2) and then add them together (result1) of (h1+h2), then do the same thing to the flowing characters from the same string (result2), and so on so fourth until I get many addition results and sum them together
S = sum(result1,result2,result3........); any idea?
Irwin2020
Irwin2020 2018 年 11 月 1 日
1-for loop for carry bit
2-for loop for extractAfter
3- for loop for hex length
Guillaume
Guillaume 2018 年 11 月 1 日
I have no idea or why you'd use for loops when they're not needed. Certainly you can add as many unneeded for loops to you code.
The code you show seem to use result1 before it is even created.
I have no idea why you use extractAfter when all you're doing is:
h1 = hex1(end-1:end)
h2 = hex2(end-1:end)
which is a lot clearer and faster.
The code you've written above seems to be a rework of my answer with some addition that don't appear to do much.
Irwin2020
Irwin2020 2018 年 11 月 1 日
here is the idea....Because when you have a 2 long hex strings and I want to add them together (regardless to their length!).. EX:
EFA885601AB2349967301010FCDEA77 + 349967301010FCDEA77EFA885601AB2 = a Hex string with the same length. The Matlab can't do this by its own, till you create a function and this function as I sated above; is to extract 77 from the first string and B2 from the second one and add them together then same the answer under (result1) and repeat the same thing for EA + 1A + (result2) , and CD + 60 = (result3) and so on so fourth, do the same thing to the entire both strings , then join the result
join([result1,result2,result3,],"")
I think this explain my idea and the function I'm trying to achieve Also , you could also or probably use extractBetween function in this process. Additionally, the whole point is to brake down any long hex string into 8, or 6, or 4 hex characters to be added.
James Tursa
James Tursa 2018 年 11 月 1 日
編集済み: James Tursa 2018 年 11 月 1 日
All of that typecasting stuff is completely unnecessary and complicated. Just using your idea of adding two hex characters at a time, here is the setup:
hex1 = 'AA10EFDE'; % arbitrary hex string
hex2 = '2FDE01CB'; % arbitrary hex string
carry = 0; % initial carry bit
nbits = ___; % bit length of the numbers
Then each iteration would contain this simple code:
h1 = _______; % code here to pick off the appropriate two hex digits
h2 = _______; % code here to pick off the appropriate two hex digits
h = dec2hex(hex2dec(h1) + hex2dec(h2) + carry,3); % force three hex digit result
hsum = h(2:3); % the two hex digit result of this iteration
carry = h(1) - '0'; % the carry bit for the next iteration
There is no need for any int32, uint32, or typecasting stuff. Just pick off the appropriate hex digits, convert them to decimal (as unsigned) and add them up, and get your resulting hex digits with the carry bit. You simply need to wrap this iteration code in a loop and put in the logic for when the loop is done and overflow checking (based on the value of nbits). The hsum results get built up into the final answer.
The logic for picking off the appropriate hex digits and concatenating the hsum iteration results could be done in several ways. E.g., shrinking the hex1 and hex2 strings by two hex digits each time, or by appropriate indexing into them, etc. I leave that to you.
The sign bit and overflow stuff will require some special code for that last iteration if the sign bit is in the "middle" instead of at the left boundary of the first hex digit. But it can be done. (That is the primary reason why the binary representation is easier to work with for this and why I suggested it).
James Tursa
James Tursa 2018 年 11 月 2 日
Putting that in a loop will be the easy part. It is the sign bit and overflow stuff that will be the hard part. Do you have any constraints on where the sign bit might be? Will it always be at the left edge of a 2-byte boundary? Or could it be anywhere? Writing generic code for a sign bit that could be anywhere could easily take up the bulk of your code and will be more complicated than what I have already written above, whereas if you restrict the cases to 2-byte boundaries that simplifies things greatly.
Guillaume
Guillaume 2018 年 11 月 2 日
all I need is that if you are able to show me a for loop (i) to add the hex values
I have done just that in the answer that at the moment is below this one.
With regards to sign bits. We still haven't had any explanation of how that work with variable length hex strings. Having a sign bit that moves around would be completely nonsensical. Would FF be the signed 8-bit decimal value -1 or the signed 16-bit decimal value 255? The only thing that would work would be if the sign bit was the LSB.

サインインしてコメントする。

Guillaume
Guillaume 2018 年 11 月 1 日

1 投票

Function to add hexadecimal strings of arbitrary length:
function hexsum = addhex(hex1, hex2)
assert(all(ismember(hex1, '0123456789ABCDEF')), 'hex1 is not a hexadecimal string');
assert(all(ismember(hex2, '0123456789ABCDEF')), 'hex2 is not a hexadecimal string');
%pad both strings to the same length and to a length multiple of 2 for easy byte conversion
maxlength = 2*ceil(max(numel(hex1), numel(hex2))/2);
hex1 = [repelem('0', maxlength - numel(hex1)), hex1];
hex2 = [repelem('0', maxlength - numel(hex2)), hex2];
%split into bytes, convert to decimal
dec1 = hex2dec(reshape(hex1, 2, [])');
dec2 = hex2dec(reshape(hex2, 2, [])');
%sum with carry
decsum = zeros(size(dec1));
carry = 0;
for row = numel(dec1):-1:1
decsum(row) = dec1(row) + dec2(row) + carry;
carry = decsum(row) > 255;
end
decsum = mod(decsum, 256);
%convert back to hex, remove leading 0
hexsum = reshape(dec2hex(decsum, 2)', 1, []);
hexsum = hexsum(~cumprod(hexsum == '0'));
end
The numbers are assumed unsigned as otherwise you would have to specify the sign bit. A loop is only needed for the addition with carry. For everything, it's simpler to do it without a loop.

カテゴリ

ヘルプ センター および File ExchangeData Type Conversion についてさらに検索

質問済み:

2018 年 10 月 22 日

コメント済み:

2018 年 11 月 24 日

Community Treasure Hunt

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

Start Hunting!

Translated by