Encoding a value in gray code with floating point with negatives - encoding

My objective here is to be able to convert any number between -4.0 and 4.0 into a 5 bit binary string using gray code. I also need to be able to convert back to decimal.
Thanks for any help you can provide.
If it helps, the bigger picture here is that i'm taking the weights from a neural network and mutating them as a binary string.

If you have only 5 bits available, you can only encode 2^5 = 32 different input values.
The Gray code is useful, if while the input values change slowly, only a single bit each changes in the coded value.
So maybe the most straightforward implementation is to map your input range -4.0 to 4.0 to the integer range 0 … 31, and then to represent these integers by a standard Gray code, which can easily be converted back to 0 … 31 and then to -4.0 to 4.0.

Related

8-bit unsigned fixed point implementation with multiplication and clamping

I'd like to represent numbers in the range [0.0, 1.0] ( optimally including both endpoints) using 8-bit words.
I'd like to be able to multiply them efficiently and addition/subtraction should optimally be clamped to [0,1], not overflow.
For example, if 0xFF would represent 1.0 and 0x00 would represent 0.0, then the multiplication should yield for example
0x3F (0.247) = 0x7F (0.499) * 0x7F (0.499)
I found https://courses.cs.washington.edu/courses/cse467/08au/labs/l5/fp.pdf and I think that what the paper would name U(0,8) corresponds to what I'm looking for, but I don't understand how multiplication for example would need to be implemented.
Is there a c++ library that efficiently implements such a data type or can someone point me to the necesseary math?
I don't need division, only multiplication, addition and subtraction
The fixed-point format you have chosen, U[0.8], does not include the exact endpoint value of 1. The maximum value in this format is actually 0.99609375. If that's close enough for you we can talk about doing the math.
Multiplying two U[0.8] values gives a 16-bit result in U[0.16] format. To convert back to U[0.8] you must shift right by 8 bit positions. So, multiplying 0x7F times 0x7F gives 0x3F01. Shifting right by 8 bits gives the U[0.8] result of 0x3F, as desired.
Two values in U[0.8] format can be added or subtracted using normal integer operations. However, you must either prevent overflow/underflow or detect overflow/underflow in the result. To detect overflow in addition you could zero-extend both values to 16 bits, perform the addition, and check to see if the result is greater than 0xFF. If so, you could saturate and return 0xFF.
For subtraction you could compare the values before doing the subtraction, and if the result would be negative just return zero.

converting 64 bits binary 1D vector into corresponding floating and signed decimal number

Please let me know how to achieve this as I tried a lot but didn't get the desired result for vector, u=[0;1;0;0;1;1;0;0;0;0;1;1;0;1;1;1;1;0;0;0;1;0;0;1;0;1;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;1;1;0;1;0;1;0;1;1;0;1;1;1;1;0;0;0;0;0;0];
desired output=-108.209
Regards
Nitin
First off, I think your expectation for a correct answer is off. The first bit in a double is the sign. So if you're expecting a negative number, the first bit should be 1. Even if you had your bits backward, it's still a leading 0. There are all sorts of binary to float calculators if you search for them. Here's an example:
http://www.binaryconvert.com/result_double.html?hexadecimal=4C378941600D5BC0
To answer your question for how to do this in Matlab, Matlab's built in function for converting from binary is bin2dec. However, it's expecting a char array as an input, so you'll need to convert to char with num2str. The other trick here is that bin2dec only supports up to 53 bits. So you'll need to break it into two 32 bit numbers. The last piece of the puzzle is to use typecast to convert your pair of 32bit integers into a double. Put it all together, and it looks like this:
bits = [0;1;0;0;1;1;0;0;0;0;1;1;0;1;1;1;1;0;0;0;1;0;0;1;0;1;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;1;1;0;1;0;1;0;1;1;0;1;1;1;1;0;0;0;0;0;0];
int1 = uint32(bin2dec(num2str(bits(1:32)')));
int2 = uint32(bin2dec(num2str(bits(33:64)')));
double_final = typecast([int2 int1],'double')

converting large numerical value to power 10 format

Is there a way to convert large numerical value to *10 to the power format in sas?
Eg: 88888888383383838383 to 8.8*10^6
Thanks in advance.
You can use the format ew. where the w the number output characters. Using e8. will result in 8.9E+19. But beware that SAS uses floating point to store values internally, with a maximum of 8 bytes. Your example value would be rounded to 88,888,888,383,383,830,528 (no matter how it's formatted).

Converting data into fixed point binary in Matlab?

I am not a regular Matlab user, so I apologize if this question is naïve. I am working on a hardware project and would like to convert some data to fixed point binary using the fixed point toolbox.
All my data are float in nature and in the range of -1 to +1. I was trying to convert them into fixed point in Matlab, to no avail.
I have been getting different types of errors, from "Cell contents assignment to non cell array objects" to just wrong binary values. Below is my code.
for i=1:count
temp=datax(i); % datax is a array of decimal values between -1 and 1
fixeda{i}=bin(sfi(temp,16,15));
% Since all values are in the same range I set the word length to be 16 and fractional part to be 15
end
I'm not a matlab user, but shouldn't the 1.15 representation of a float between -1 and 1 just be int(f*32768)
Note that you can only represent numbers less than 1.0 in this representation. 1.0 exactly causes an overflow.
Looking at the help pages it looks like fixeda = bin(sfi(datax,16,15)) should be all you need.

Random Number in Octave

I need to generate a random number that is between .0000001 and 1, I have been using rand(1) but this only gives me 4 decimal points, is there any other way to do this generation?
Thanks!
From the Octave docs:
By default, Octave displays 5 significant digits in a human readable form (option ‘short’ paired with ‘loose’ format for matrices).
So it's probably an issue with the way you're printing the value rather than the value itself.
That same page shows the other output formats in addition to short, the one you may want to look in to is long, giving 15 significant digits.
And there is also the output_precision which can be set as per here:
old_val = output_precision (7)
disp (whatever)
old_val = output_precision (old_val)
Set the output_precision to 7 and it should be ok :)
Setting the output precision won't help though because the number can still be less than .0000001 in theory but you will only be displaying the first 7 digits. The simplest way is:
req=0;
while (req<.0000001)
req=rand(1);
end
It is possible that this could get you stuck in a loop but it will produce the right number. To display all the decimals you can also use the following command:
format long
This will show you 15 decimal places. To switch back go:
formay short