Search code examples
matlabmathbinaryfixed-point

fixed point binary operation with matlab


I have these decimal values:

x1=-43.00488
x4=11.5048
y1=-11.5048
y4=-43.004  

I converted them to their equal binary values, in the format Q7.10

So, these are the binary values:

% All of the binary values are signed and in Q7.10 format.

x1=1010100_1111111011   
x4=0001011_1000000101
y1=1110100_0111111011
y4=1010100_1111111011

I want to do this operation with binary values in matlab :

% This line is equal to multiplying "((x1-x4) / (y1-y4))" with 2^10;

 x1x4_div_y1y4 = ((x1-x4) / (y1-y4)) << 10  

While trying to do this operation I had some difficulties,

firstly, I couldn't declare the negative binary values in Matlab. secondly, are we allowed to do math operations with binary values or should I do the operations with decimal values then convert them to binary values?

But what I need is to do this operation with binary operations so I can implement it in verilog hdl.

  a= ((-43.00488-11.5048) / (-11.5048+43.00488))*(2^10)

a =

  -1.7720e+03

I am not sure if these statements are given the true answer. Should I multiply it with 2^10 or so...

I want to do the same operation using binary values. Can I do that in Matlab? And how to do that?

Thank you in advance.


Solution

  • Your question is not very clear. I think you probably need to think about what you want the fixed-point format of x1x4_div_y1y4 to be. I'm not sure if you really want to multiply by 2^10, or you just did that because you thought you needed to.

    However, since you stated that's the operation you want to do, I will assume you really wanted to multiply by 2^10.

    The code below converts the binary numbers to fixed point, does the calculation you want, then converts the result back to binary.

    Your decimal result (-1772) was correct. You just need to convert it back to signed binary. However, be careful because this number cannot be represented in Q7.10 format (because you multiplied by 2^10, so now it's too large).

    In the code below, I just assumed you want the result in signed Q16.8 format (which I interpret as 1 sign bit + 16 integer bits + 8 fractional bits). If you want something different, you can just change those numbers.

    close all; clear all; clc;
    
    % All of  the binary values are signed and in Q7.10 format.
    x1 = '10101001111111011';
    x4 = '00010111000000101';
    y1 = '11101000111111011';
    y4 = '10101001111111011';
    
    % Convert to signed integers
    x1 = -bin2dec(x1(1))*2^16 + bin2dec(x1(2:end));
    x4 = -bin2dec(x4(1))*2^16 + bin2dec(x4(2:end));
    y1 = -bin2dec(y1(1))*2^16 + bin2dec(y1(2:end));
    y4 = -bin2dec(y4(1))*2^16 + bin2dec(y4(2:end));
    
    % Convert from integer to fixed point values
    x1 = x1 / 2^10;
    x4 = x4 / 2^10;
    y1 = y1 / 2^10;
    y4 = y4 / 2^10;
    
    % The operation I want to do
    x1x4_div_y1y4 = ((x1-x4) / (y1-y4)) * 2^10; % << 10
    
    % Convert back to binary...
    
    % Let's assume we want signed Q16.8 output
    INTEGER_BITS = 16;
    FRACTIONAL_BITS = 8;
    
    % Convert from fixed-point to integer
    x1x4_div_y1y4 = round(x1x4_div_y1y4 * 2^FRACTIONAL_BITS);
    
    % Handle the sign bit
    if x1x4_div_y1y4 < 0
        x1x4_div_y1y4 = x1x4_div_y1y4 + 2*2^(INTEGER_BITS + FRACTIONAL_BITS);
    end
    
    % Convert to binary
    x1x4_div_y1y4 = dec2bin(x1x4_div_y1y4, 1+INTEGER_BITS+FRACTIONAL_BITS)