Why does 0x8FFFFFF equal 128MB? - hex

I sometimes see code like this:
int length = 0x8FFFFFF; //128MB
byte buf = new byte[length];
It does not make much sense to me as:
0x8FFFFFF = 150,994,943
128MB = 128 * 1024 * 1024 byte = 134,217,728 byte
These two number does not equal. What am I missing here?
Thanks,

Someone previously had a 7 there but changed it to a 8 in order to avoid an off-by-one error, but forgot to change the rest to 0.

Well, 0x7FFFFFF = 134217727, so 128MB should be 0x8000000

Related

Variable runover when not reaching the limit yet

My variable had a Runover even before it reached its range.
Currently, I am working with timer 2 with a frequency of 90MHz. When I retrieved the current time by __HAL_TIM_GET_COUNTER() and printed it by printf("receive_time: %lu\n", (unsigned long)receive_time), the maximum the receive_time get is 16 bits although I declared it as 32 bits. I observed the printed value and it never exceeded 2^16 -1.
I also tried to print with printf("%" PRIu32 "\n",a); but it also returned the same.
I had another 32-bit variable send_time which is used later to subtract with receive_time. However, it gave me something in the order of 2*10^9 (2147482170 for example) besides some common values.
I want to ask what happen and if I do something wrong. If everything is correct, is there any way to handle the rollover besides having 2 timers starting at different times?
The code is here:
Radio::radio.tx_buf[0] = seq++; /* set payload */
printf("send a ready message\r\n");
Radio::Send(1, 0, 0, 0); /* begin transmission */
send_time = __HAL_TIM_GET_COUNTER(&htim2);
.
.
.
if (Radio::radio.rx_buf[0] == 100)
{
receive_time = __HAL_TIM_GET_COUNTER(&htim2);
printf("receive_time: %lu\n", (unsigned long)receive_time);
printf("send_time: %lu\n", (unsigned long)send_time);
time_difference = (receive_time - send_time)/2;
printf("time_difference: %lu\n", (unsigned long)time_difference);
uint32_t distance = time_difference * 10 / 3;
printf("Distance: %lu\n", (unsigned long)distance);
}```
Thank you in advanced,
Huy Nguyen.

How to create an array of references to arrays?

I'm having some syntax troubles with my code. A bit of context...
My program has a schedule, it's an array of 24 bytes. There's one schedule per day, so 7 arrays.
I want to have a single array of 7 elements storing references to the above 7 arrays. This way, by calling schedules[1], I get schedule1[24], which is Monday.
// One schedule per day (0 = sunday)
byte schedule0[24];
byte schedule1[24];
byte schedule2[24];
byte schedule3[24];
byte schedule4[24];
byte schedule5[24];
byte schedule6[24];
byte * schedules[7] = {&schedule0, &schedule1};
The problem comes from the last line, the error being "a value of type "byte (*)[24]" cannot be used to initialize an entity of type "byte *" ".
I tried inserting [24] before or after the star/pointer character, with no luck.
Could any of you please show me the correct syntax to do this?
In C++, name of the array is the pointer to the first element in the array. So in your case schedule0 is a pointer to &schedule0[0] not &schedule0.
You can change the last line as
byte * schedules[2] = {&schedule0[0], &schedule1[0]}; or byte * schedules[2] = {schedule0, schedule1};
This will create a pointer array containing the base address of the scheduleX arrays.
I want to have a single array of 7 elements storing references to the above 7 arrays. This way, by calling schedules[1], I get schedule1[24], which is Monday.
A different approach is needed to index across days. This can be done using a two dimensional array and some pointer arithmetic.
Declare a two dimensional array for your schedules:
byte schedulesArray[7][24];
Declare pointers that point to the schedules for each day:
byte *schedule0 = &schedulesArray[0][0];
byte *schedule1 = &schedulesArray[1][0];
byte *schedule2 = &schedulesArray[2][0];
byte *schedule3 = &schedulesArray[3][0];
byte *schedule4 = &schedulesArray[4][0];
byte *schedule5 = &schedulesArray[5][0];
byte *schedule6 = &schedulesArray[6][0];
Declare a pointer to the first element of the two dimensional array:
byte *schedules = &schedulesArray[0][0];
So if we seed some data:
schedule0[0] = 1;
schedule1[0] = 11;
schedule1[1] = 12;
schedule2[0] = 21;
schedule2[1] = 22;
Then you can use the schedules pointer to index across days:
schedules[0]; // = 1
schedules[24]; // = 11
schedules[25]; // = 12
schedules[48]; // = 21
schedules[49]; // = 22
This works because multidimensional arrays are laid out as a contiguous block of memory.
Simply, you can't do it.
And here is explanation why:
Basically, a reference is an alias to an existing variable. This means, if you apply any operation on a reference, it will behave as if you were using the original variable name. And there are no references at a reference or pointer at references, references don't allocate any memory so there is nothing that you can use to put in an array.
What you can do is create an array of pointers and it will work.

AX2009 str type limited to 1000 characters

I need to store a Xml buffer somewhere before processing it with XmlDocument. This can be done in a temporary file but I would prefer to work in memory.
I try to use a str 10000 buffer, but I discovered that in my configuration, it is limited to 1000.
Example :
str 2000 strTest;
int i;
for (i=1; i<= 200; i++)
{
strTest = strTest + "1234567890";
info(strfmt("Length : %1", strlen(strTest)));
}
In the infolog I see that the Length remains stuck at the maximum value of 1000.
Here is another question looking similar but I don't read a solution in it
I discover that the example works if I replace str 2000 strTest by str strTest.
So the limit of 1000 applies only if we specify a size for the string, this can be seen only if the specified size is bigger than 1000.
This has the appearance of a small bug in AX.

Convert ByteArray to Integer in Flex

Can someone shed some lights on how to convert ByteArray into int?
Thanks,
So to get a flavor of doing this, you can try this bit of code:
function test(){
var bytes:ByteArray = new ByteArray();
bytes.writeInt(0x00DDAA99); //create my byte array with int 14527129
bytes.position = 0; //move the postion to the start
var newInt:int = bytes.readInt(); //read the bytes from starting position
trace("new num: "+newInt); //print out the number
}
This code will first create a byte array and put an int into it. This is presumably where you need your code to start. This then makes the assumption that there are 4 bytes to read after the starting position which I have set to 0. It then reads the 4 bytes off the byte array into the queue. Note that if you do not have 4 bytes in your ByteArray or your position is not set correctly, your code will fail. Make sure you add the checks for those scenarios.
This code also assumes that the byte array is Big Endian. Make sure that if you have a byte array from another system, that you know which endian-ness the int value has. Change the endian value on your byte array if needed.

Get four 16bit numbers from a 64bit hex value

I have been through these related questions:
How to convert numbers between hexadecimal and decimal in C#?
How to Convert 64bit Long Data Type to 16bit Data Type
Way to get value of this hex number
But I did not get an answer probably because I do not understand 64bit or 16bit values.
I had posted a question on Picasa and face detection, to use the face detection that Picasa does to get individual pics from a photo containing many pictures. Automatic Face detection using API
In an answer #Joel Martinez linked to an answer on picasa help which said:
The number encased in rect64() is a 64-bit hexadecimal number.
Break that up into four 16-bit numbers.
Divide each by the maximum unsigned 16-bit number (65535) and you'll have four
numbers between 0 and 1.
the full text
#oedious wrote:- This is going to be
somewhat technical, so hang on. * The
number encased in rect64() is a 64-bit
hexadecimal number. * Break that up
into four 16-bit numbers. * Divide
each by the maximum unsigned 16-bit
number (65535) and you'll have four
numbers between 0 and 1. * The four
numbers remaining give you relative
coordinates for the face rectangle:
(left, top, right, bottom). * If you
want to end up with absolute
coordinates, multiple the left and
right by the image width and the top
and bottom by the image height.
A sample picasa.ini file:
[1.jpg]
backuphash=65527
faces=rect64(5520c092dfb2f8d),615eec1bb18bdec5;rect64(dcc2ccf1fd63e93e),bc209d92a3388dc3;rect64(52524b7c785e6cf6),242908faa5044cb3
crop=rect64(0)
How do I get the 4 numbers from the 64 bit hex?
I am sorry people, currently I do not understand the answers. I guess I will have to learn some C++ (I am a PHP & Java Web Developer with weakness in Math) before I can jump in and write a something which will cut up an image into multiple images with the help of some co-ordinates. I am looking into CodeLab and creating plugins for Paint.net too
If you want basics, say you have this hexadecimal number:
4444333322221111
We split it into your 4 parts on paper, so all that's left is to extract them. This involves using a ffff mask to block out everything else besides our number (f masks nothing, 0 masks everything) and sliding it over each part. So we have:
part 1: 4444333322221111 & ffff = 1111
part 2: 4444333322221111 & ffff0000 = 22220000
part 3: 4444333322221111 & ffff00000000 = 333300000000
part 4: 4444333322221111 & ffff000000000000 = 4444000000000000
All that's left is to remove the 0's at the end. All in all, in C, you'd write this as:
int GetPart(int64 pack, int n) // where you define int64 as whatever your platform uses
{ // __int64 in msvc
return (pack & (0xffff << (16*n)) >> (16*n);
}
So basically, you calculate the mask as 0xffff (2 bytes) moved to the right 16*n bits (0 for the first, 16 for the 2nd, 32 for the 3rd and 48 for the 4th), apply it over the number to mask out everything but the part we're interested in, then shift the result back 16*n bits to clear out those 0's at the end.
Some additional reading: Bitwise operators in C.
Hope that helps!
Here is the algorithm:
The remainder of the division by 0x10000 (65536) will give you the first number.
Take the result then divide by 0x10000 (65536) again, the remainder will give you the second number.
Take the result the divide by 0x10000 (65536) again, the remainder will give you the third number.
The result is the fourth number.
It depends on your programming language - in C# i.e. you can use the BitConverter class, which allows you to extract a number based on the byte position within a byte array.
UInt64 largeHexNumber = 420404334;
byte[] hexData = BitConverter.GetBytes(largeHexNumber);
UInt16 firstValue = BitConverter.ToUInt16(hexData, 0);
UInt16 secondValue = BitConverter.ToUInt16(hexData, 2);
UInt16 thirdValue = BitConverter.ToUInt16(hexData, 4);
UInt16 forthValue = BitConverter.ToUInt16(hexData, 6);
It depends on the language. For the C-family of languages, it can be done like this (in C#):
UInt64 number = 0x4444333322221111;
//to get the ones, use a mask
// 0x4444333322221111
const UInt64 mask1 = 0xFFFF;
UInt16 part1 = (UInt16)(number & mask1);
//to get the twos, use a mask then shift
// 0x4444333322221111
const UInt64 mask2 = 0xFFFF0000;
UInt16 part2 = (UInt16)((number & mask2) >> 16);
//etc.
// 0x4444333322221111
const UInt64 mask3 = 0xFFFF00000000;
UInt16 part3 = (UInt16)((number & mask3) >> 32);
// 0x4444333322221111
const UInt64 mask4 = 0xFFFF000000000000;
UInt16 part4 = (UInt16)((number & mask4) >> 48);
What I think you are being asked to do is take the 64 bits of data you have and treat it like 4 16-bit integers. From there you are taking the 16-bit values and converting them to percentages. Those percentages, when multiplied to the image height/width, give you 4 coordinates.
How you do this depends on the language you're programming in.
I needed to convert the crop=rect64() values from picasa.ini file.
I created the following ruby method with the above information.
def coordinates(hex_num)
[
hex_num.divmod(65536)[1],
hex_num.divmod(65536)[0].divmod(65536)[1],
hex_num.divmod(65536)[0].divmod(65536)[0].divmod(65536)[1],
hex_num.divmod(65536)[0].divmod(65536)[0].divmod(65536)[0].divmod(65536)[1]
].reverse
end
It works, but I needed to add the .reverse method on the array to achieve the desired result.

Resources