print binary strings to a textfile with specific row lengths - matlab

Unix+matlab R2016b
I have a 1 dim table with numbers that I'd like to export to a 12-bit binary table in a text file.
x = [0:1:250];
a = exp(-((x*8)/350));
b = exp(-((x*8)/90));
y = a-b;
y_12bit = y*4095;
y_12bitRound = ceil(y_12bit);
y_12bitRoundBinary = de2bi(y_12bitRound,12);
fileID = fopen('expo_1.txt','w');
fprintf(fileID,'%12s',y_12bitRoundBinary);
Now, y_12bitRoundBinary looks good when i print this in the console.
y_12bitRoundBinary =
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0
0 0 1 0 0 1 1 1 1 0 0 0
0 0 0 0 1 1 0 1 0 1 0 0
0 0 1 0 0 1 1 0 1 1 0 0
0 0 1 0 0 0 0 0 0 0 1 0
This looks good, but I would like the bit order to be reversed. The MSBs are towards the right and I would like a little-endian ordering. Also, I don't know if this printing actually proves that y_12bitRoundBinary is correct.
Are there spaces in between each bit or is this just the format of the printing function?
How to change the ordering?
The first lines of the data written to file expo_1.txt:
0000 0000 0000 0000 0000 0101 0001 0001
0001 0000 0101 0001 0101 0100 0000 0100
0101 0000 0000 0100 0100 0101 0000 0100
0000 0001 0001 0101 0100 0100 0000 0100
0101 0101 0001 0101 0000 0101 0101 0100
0100 0000 0101 0001 0101 0101 0100 0101
As you see, the data is beyond recognition compared with how y_12bitRoundBinary was printed in the Matlab console.
Would anyone have any pointers on where my mistake is concerning the data written to file?

Assuming that you would like to print the numbers as ASCII strings, this will work
x = 0:250;
a = exp(-((x*8)/350));
b = exp(-((x*8)/90));
y = a-b;
% Reduce to 12 bit precision
y_12bit = y*2^12;
y_12bitRound = floor(y_12bit);
% Convert y_12bitRound to char arrays with 12 bits precision
y_12bitCharArray = dec2bin(y_12bitRound,12);
% Convert to cell array of string
y_12bitCellArray = cellstr(y_12bitCharArray);
fileID = fopen('expo_1.txt','wt');
fprintf(fileID,'%s\n', y_12bitCellArray{:});
fclose(fileID);
This will print the following to the file expo_1.txt
000000000000
000011111111
000111100100
001010101111
001101100011
010000000011
010010010000
...
The trick is to convert the char array to a cell array of strings, which is easier to print as desired, using the {:} operator to expand the cell array.

Related

Why `GO` integer `uint32` numbers are not equal after being converted to `float32`

Why is the float32 integer part inconsistent with the original uint32 integer part after uint32 integer is converted to float32, but the float64 integer part is consistent with the original uint32 after converting it to float64.
import (
"fmt"
)
const (
deadbeef = 0xdeadbeef
aa = uint32(deadbeef)
bb = float32(deadbeef)
)
func main() {
fmt.Println(aa)
fmt.Println("%f",bb)
}
The result printed is:
3735928559
3735928576.000000
The explanation given in the book is that float32 is rounded up
Analyzed the binary information of 3735928559, 3735928576
3735928559: 1101 1110 1010 1101 1011 1110 1110 1111
3735928576: 1101 1110 1010 1101 1011 1111 0000 0000
It is found that 3735928576 is the result of setting the last eight positions of 3735928559 to 0 and the ninth last position to 1.
And this case is the result of rounding off the last 8 digits
const (
deadbeef = 0xdeadbeef - 238
aa = uint32(deadbeef)
bb = float32(deadbeef)
)
func main() {
fmt.Println(aa)
fmt.Printf("%f",bb)
}
The result printed is:
3735928321
3735928320
Its binary result is
3735928321:1101 1110 1010 1101 1011 1110 0000 0000
3735928320:1101 1110 1010 1101 1011 1110 0000 0001
Why float32(deadbeef) integer part is not equal to uint32(deadbeef) integer part? no fractional part after deadbeef
Why float32(deadbeef) integer part differs from uint32(deadbeef) integer part by > 1
Why does this happen? If there is rounding up or down, what is the logic?
Because the precision range of float is not complete enough to represent the part of uint32, the real effective number of digits is actually seriously insufficient.
The precision of float32 can only provide about 6 decimal digits (after representing post-scientific notation, 6 decimal places)
The precision of float64 provides about 15 decimal digits (after representing post-scientific notation, 15 decimal places)
So it's normal for this to happen.
And this is not only the Go language that will exist, but all languages that need to deal with this will have this problem.

Logical equality for two different vector widths

Why does logical equality for two vectors of different widths have an output like below?
module eq_test;
logic check;
logic [3:0] cmp_0;
logic cmp_1 = 1'b0;
initial begin
for (int i = 0; i < 16; i++) begin
cmp_0 = i;
check = (cmp_0 == cmp_1);
$display("%b == %b is %b", cmp_0, cmp_1, check);
end
end
endmodule
With Vivado Simulator
0000 == 0 is 1
0001 == 0 is 0
0010 == 0 is 0
0011 == 0 is 0
0100 == 0 is 0
0101 == 0 is 0
0110 == 0 is 0
0111 == 0 is 0
1000 == 0 is 0
1001 == 0 is 0
1010 == 0 is 0
1011 == 0 is 0
1100 == 0 is 0
1101 == 0 is 0
1110 == 0 is 0
1111 == 0 is 0
I can assume that the variable with smaller width cmp_1 is expanded (unsigned expand) to the larger variable width cmp_0, is that so?
Yes, the variable with smaller width is expanded to the larger variable width.
This is described in IEEE Std 1800-2017, section 11.6.1 Rules for expression bit lengths.
The number of bits of an expression (known as the size of the
expression) shall be determined by the operands involved in the
expression and the context in which the expression is given.
In Table 11-21, the == operator has this comment:
Operands are sized to max(L(i),L(j))
where i and j represent expressions of an operand, and L(i) represents the bit length of the operand represented by i.
This is true for all simulators, not just for Vivado.

Octave/matlab: uint8 array to float

I'm receiving Big-endian data from a socket (using the socket package) in Octave.
Some parts of this data contain float (32bit) values, but these are encoded as uint8's.
For example: (67 128 0 0)
Is there a way in Octave to calculate the corresponding float/single value?
The way to do it is using typecast():
octave> typecast (uint8 ([67 128 0 0]), "single")
ans = 4.6012e-41
If you have an endianess issue, use swapbytes():
octave> swapbytes (typecast (uint8 ([67 128 0 0]), "single"))
ans = 256
If you want to play more with it, or require more flexibility, take also a look at bitpack() and bitunpack():
octave> data = uint8 ([67 128 0 0 67 127 0 0 67 126 0 0 67 125 0 0])
data =
67 128 0 0 67 127 0 0 67 126 0 0 67 125 0 0
octave> bitpack (bitunpack (flipud (reshape (data, 4, []))), "single")
ans =
256
255
254
253

Convert a matrix of type char to type logical in matlab

Hello I have a char matrix that represents a binary numbers. For example:
0000
1010
0111
.
.
.
1010
How can I convert it to a logical matrix?
You can compare it with character '1'
>> A=['0101';'1011']
A =
0101
1011
>> A=='1'
ans =
0 1 0 1
1 0 1 1
Is this what you want?
a = {'0000'; '1010'; '0111'};
b = logical(double(cell2mat(a)) - 48);
gives,
>> b
b =
0 0 0 0
1 0 1 0
0 1 1 1
>> class(b)
ans =
logical
Try
b_bin = logical(b(:)'-'0')
if b is the name of your matrix.

Decoding a Time and Date Format

The Olympus webserver on my camera returns dates the I cannot decode to a human readable format.
I have a couple of values to work with.
17822 is supposed to be 30.12.2014
17953 is supposed to be 01.01.2015 (dd mm yyyy)
17954 is supposed to be 02.01.2015
So I assumed this was just the number of days since xxx and it turns out this is 05.11.1965, so I guess this is wrong.
Also the time is an integer value as well.
38405 is 18:48
27032 is 13:12
27138 is 13:16
The right values are UTC+1
Maybe somebody has an idea how to decode these two formats.
They are DOS timestamps
dos timestamps are a bitfield format with the parts of the date and time encoded into adjacent bits in the number, here are some worked examples.
number hex binary
17822 0x459E = 0010 0101 1001 1110
YYYY YYYM MMMD DDDD
Y=001 0010 = 34 ( add 1980 to get 2014)
M=1100 = 12
D=1 1110 = 30
17953 0x4621 = 0010 0110 0010 0001
Y=001 0011 = 35 (2015)
M=0001 = 1
D=0 0001 = 1
17954 0x4622 = 0010 0110 0010 0010
Y=001 0011 = 35 (2015)
M=0001 = 1
D=0 0010 = 2
and the times are simiilar
38405 = 0x9605 = 1001 0110 0000 0101
HHHH HMMM MMMS SSSS
H= 1 0010 = 18
M=11 0000 = 48
S= 0 0101 = 5 (double it to get 10)