Non invasive way for a debug print into ram file - c

I'm looking for a non invasive way of writing a local variable into a file to use it as a debugging mechanism. The non invasive part means that the debug code should have as little execution time as possible and should minimally interfere with the method that's being debugged.
Example:
Somewhere deep inside the code there is a method.
unsigned int method(short *frame, int length)
{
process-frame(short *frame, int length);
}
It gets called 100 times a second and I would like to print out the content of frame. Since the process is time sensitive I can't print to the terminal but will print into the file in ram. Am looking for a way to do it inside the function scope.

The best I've come so far is this. Am open for other answers with a more optimized approach
unsigned int method(short *frame, int length)
{
static FILE * rawPcmLog;
if (rawPcmLog == NULL) rawPcmLog = fopen("/tmp/rawPcm","w");
int i;
for (i=0; i<length; i++){
fwrite(frame,length, 1,rawPcmLog);
}
process-frame(short *frame, int length);
}

Related

How can I create a function object in C

I would like to create a wrapper for c functions, so that I can convert a function call of the form ret = function(arg1,arg2,arg3); into the form /*void*/ function_wrapper(/*void*/);. That is similar to function objects in C++ and boost bind.
Is this possible? how can I do it?
Update:
To explain in more details what I am looking for:
We start with this function:
int f(int i){
//do stuff
return somevalue;
}
Obvioulsy, it is called like this:
// do stuff
int x = 0;
ret = f(0);
// do more stuff.
I would like to do some magic that will wrap the function into void function(void)
struct function_object fo;
fo.function_pointer = &f;
fo.add_arg(x, int);
fo.set_ret_pointer(&ret);
fo.call();
Note: I saw that there was a vote for closing this question and marking it as unclear. Please do not do that. I have a legitimate need to get this question answered. If you need explanation, ask and I will be glad to elaborate.
I came up with a better code that might allow you to do what you want. First I'll explain how it works, show the code and explain why I still don't think it's a good idea to use it (though the code might open doors for improvements that addresses those issues).
Functionality:
Before you start using the "function objects", you have to call an initialization function (FUNCTIONOBJ_initialize();), which will initialize the mutexes on every data structure used in the library.
After initializing, every time you want to call one of those "function objects", without using the parameters, you will have to set it up first. This is done by creating a FUNCTIONOBJ_handler_t pointer and calling get_function_handler(). This will search for a free FUNCTIONOBJ_handler data structure that can be used at the moment.
If none is found (all FUNCTIONOBJ_handler data structures are busy, being used by some function call) NULL is returned.
If get_function_handler() does find a FUNCTIONOBJ_handler data structure it will try to lock the FUNCTIONOBJ_id_holder data structure, that holds the ID of the FUNCTIONOBJ_handler of the function about to be called.
If FUNCTIONOBJ_id_holder is locked already, get_function_handler() will hang until it's unlocked by the thread using it.
Once FUNCTIONOBJ_id_holder is locked, the ID of the grabbed FUNCTIONOBJ_handler is wrote on it and the FUNCTIONOBJ_handler pointer is returned by get_function_handler.
With the pointer in hand, the user can set the pointer to the arguments and the return variable with set_args_pointer and set_return_pointer, which both take a void * as arguments.
Finally, you can call the function you want. It has to:
1 - Grab the FUNCTIONOBJ_handler ID from the FUNCTIONOBJ_id_holder data structure and use it to get a pointer to the FUNCTIONOBJ_handler itself.
2 - Use the FUNCTIONOBJ_handler to access the arguments.
3 - Return by using one of the return function (on the example we have ret_int, which will return an integer and unlock the FUNCTIONOBJ_handler)
Below is a simplified mind map describing a bit of what is going on:
Finally, the code:
funcobj.h:
#include <stdio.h>
#include <pthread.h>
#define MAX_SIMULTANEOUS_CALLS 1024
typedef struct {
//Current ID about to be called
int current_id;
//Mutex
pthread_mutex_t id_holder_mutex;
} FUNCTIONOBJ_id_holder_t;
typedef struct {
//Attributes
void *arguments;
void *return_pointer;
//Mutex
pthread_mutex_t handler_mutex;
} FUNCTIONOBJ_handler_t;
FUNCTIONOBJ_handler_t FUNCTIONOBJ_handler[MAX_SIMULTANEOUS_CALLS];
FUNCTIONOBJ_id_holder_t FUNCTIONOBJ_id_holder;
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value);
void FUNCTIONOBJ_initialize(void);
FUNCTIONOBJ_handler_t *get_function_handler(void);
funcobj.c:
#include "funcobj.h"
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->return_pointer = pointer;
}
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->arguments = pointer;
}
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value){
if(this->return_pointer){
*((int *) (this->return_pointer)) = return_value;
}
pthread_mutex_unlock(&(this->handler_mutex));
}
void FUNCTIONOBJ_initialize(void){
for(int i = 0; i < MAX_SIMULTANEOUS_CALLS; ++i){
pthread_mutex_init(&FUNCTIONOBJ_handler[i].handler_mutex, NULL);
}
pthread_mutex_init(&FUNCTIONOBJ_id_holder.id_holder_mutex, NULL);
}
FUNCTIONOBJ_handler_t *get_function_handler(void){
int i = 0;
while((0 != pthread_mutex_trylock(&FUNCTIONOBJ_handler[i].handler_mutex)) && (i < MAX_SIMULTANEOUS_CALLS)){
++i;
}
if(i >= MAX_SIMULTANEOUS_CALLS){
return NULL;
}
//Sets the ID holder to hold this ID until the function is called
pthread_mutex_lock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
FUNCTIONOBJ_id_holder.current_id = i;
return &FUNCTIONOBJ_handler[i];
}
main.c:
#include "funcobj.h"
#include <string.h>
//Function:
void print(void){
//First the function must grab the handler that contains all its attributes:
//The FUNCTIONOBJ_id_holder is mutex locked, so we can just access its value and
//then free the lock:
FUNCTIONOBJ_handler_t *this = &FUNCTIONOBJ_handler[FUNCTIONOBJ_id_holder.current_id];
//We dont need the id_holder anymore, free it!
pthread_mutex_unlock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
//Do whatever the function has to do
printf("%s\n", (char *) this->arguments);
//Return the value to the pointed variable using the function that returns an int
ret_int(this, 0);
}
void *thread_entry_point(void *data){
int id = (int) data;
char string[100];
snprintf(string, 100, "Thread %u", id);
int return_val;
FUNCTIONOBJ_handler_t *this;
for(int i = 0; i < 200; ++i){
do {
this = get_function_handler();
} while(NULL == this);
set_args_pointer(this, string);
set_return_pointer(this, &return_val);
print();
}
return NULL;
}
int main(int argc, char **argv){
//Initialize global data strucutres (set up mutexes)
FUNCTIONOBJ_initialize();
//testing with 20 threads
pthread_t thread_id[20];
for(int i = 0; i < 20; ++i){
pthread_create(&thread_id[i], NULL, &thread_entry_point, (void *) i);
}
for(int i = 0; i < 20; ++i){
pthread_join(thread_id[i], NULL);
}
return 0;
}
To compile: gcc -o program main.c funcobj.c -lpthread
Reasons to avoid it:
By using this, you are limiting the number of "function objects" that can be running simultaneously. That's because we need to use global data structures to hold the information required by the functions (arguments and return pointer).
You will be seriously slowing down the program when using multiple threads if those use "function objects" frequently: Even though many functions can run at the same time, only a single function object can be set up at a time. So at least for that fraction of time it takes for the program to set up the function and actually call it, all other threads trying to run a function will be hanging waiting the the data structure to be unlocked.
You still have to write some non-intuitive code at the beginning and end of each function you want to work without arguments (grabbing the FUNCTIONOBJ_handler structure, unlocking the FUNCTIONOBJ_id_holder structure, accessing arguments through the pointer you grabbed and returning values with non-built-in functions). This increases the chances of bugs drastically if care is not taken, specially some nasty ones:
Increases the chances of deadlocks. If you forget to unlock one of the data structures in any point of your code, you might end up with a program that works fine at some moments, but randomly freeze completely at others (because all function calls without arguments will be hanging waiting for the lock to be freed). That is a risk that happens on multithreaded programs anyways, but by using this you are increasing the amount of code that requires locks unnecessarily (for style purposes).
Complicates the use of recursive functions: Every time you call the function object you'll have to go through the set up phrase (even when inside another function object). Also, if you call the recursive function enough times to fill all FUNCTIONOBJ_handler structures the program will deadlock.
Amongst other reasons I might not notice at the moment :p

General function for executing time measurement

I'm currently trying to write a general function to measure the time another function func needs for execution. I'm able to calculate the time with <time.h> and so on.
My approach looks something like this:
void measure_time(void *(func)(), unsigned loops);
For now it is enough if the result is just printed within measure_time (later I could let measure_time return some information).
I'm able to calculate the execution time and so on (with <time.h>) but at the moment my problem is that I want this to be a general function and it should be able to take all sort of functions 'func' with different return types and different argument sizes/types.
Currently I have no clue how I could manage to give measure_time the function 'func' and let it execute it with arguments I am able to specify.
For example:
int a[1000] = {15, 53, ..., 42};
void sort_something(int *a, int n_elements) { ... };
void measure_time(sort_somthing(a, 1000), 100);
This should call sort_something 100 times with the arguments "a and 1000" and measure the time needed for the execution.
I'm more than happy to give some more information if you need them.
Cheers!
LastSeconds
The general scheme should be:
void general_timer(void (*function)(void *context), void *context, int loops);
This takes a function that returns no value and takes a single void * argument for context, and passes the context. Depending on what you need to pass as context, that might be the address of a structure, or something as simple as a FILE *.
Inside the implementation:
void general_timer(void (*function)(void *context), void *context, int loops)
{
Clock clk;
clk_init(&clk);
clk_start(&clk);
for (int i = 0; i < loops; i++
(*function)(context);
clk_stop(&clk);
char buffer[32];
printf("%s seconds for %d iterations\n",
clk_elapsed_microsecs(&clk, buffer, sizeof(buffer)), loops);
}
Where the type Clock and the functions starting clk_ are parts of a high-resolution timing package, using whatever is convenient.
You could write the function call as:
function(context);
It would work exactly the same. This is the more modern style; I prefer the old-fashioned (*function)(context) call as it makes it clear that function is a function pointer, not the name of a function. YMMV.
Yes, I do have a specific implementation of such a package. However, the concept applies readily regardless of how you implement it.
You might have a function to be timed. It might use the structure:
struct TwoFiles
{
FILE *f_in;
FILE *f_out;
};
and the function might be:
void file_copier(void *ctxt)
{
struct TwoFiles *info = ctxt;
char buffer[4096];
size_t bytes;
rewind(info->f_in);
rewind(info->f_out);
while ((bytes = fread(buffer, sizeof(buffer), sizeof(char), info->f_in)) > 0)
{
if (frwite(buffer, bytes, sizeof(char), info->f_out) != bytes)
{
…report error…abandon loop…
}
}
}
and the call might be:
struct TwoFiles ctxt;
ctxt.f_in = fopen(some_file_name, "r");
ctxt.f_out = fopen(another_name, "w");
general_timer(file_copier, &ctxt, 100);
Note that to be useful, the file copier function needed to rewind the input and output file streams so that it would do work each time the general timer function calls it. That is, however, a detail for the specific task on hand.

Error of mexfunction variables in an array of a structure variable

Recently, I tried to write mexfunctions using structure variables.
I watched the tutorial but got confused because of how the variable values are passed.
The following example (mexfunction_using_ex_wrong.m & mexfunction_using_ex_wrong.cpp) demonstrates how to fetch the variables passed from matlab in mexfunction.
However, in this case, the result is:
address i_c1=2067094464 i_c2=2067094464
i_c1=10 i_c2=10
address i_c1=1327990656 i_c2=2067100736
i_c1=2 i_c2=20
address i_c1=2067101056 i_c2=2067063424
i_c1=3 i_c2=30
As can be seen, the 1st element of the c1 & c2 array of a structure variable is accidentally the same.
But, in another example (mexfunction_using_ex_correct.m & mexfunction_using_ex_correct.cpp), the elements of array 1 (b1) and array 2(b2) of a structure variable are unrelated as I expect.
The result is:
address i_b1=1978456576 i_b2=1326968576
i_b1=1 i_b2=10
address i_b1=1978456584 i_b2=1326968584
i_b1=2 i_b2=20
address i_b1=1978456592 i_b2=1326968592
i_b1=3 i_b2=30
However, it's more common to use the 1st example in programming. so could anybody explain why in the 1st example the addresses of i_c1 & i_c2 are the same?
The following code is mexfunction_using_ex_wrong.m
clc
clear all
close all
mex mexfunction_using_ex_c_wrong.cpp;
a.b(1).c1=double(1);
a.b(2).c1=double(2);
a.b(3).c1=double(3);
a.b(1).c2=double(1);
a.b(2).c2=double(2);
a.b(3).c2=double(3);
mexfunction_using_ex_c_wrong(a);
The following code is mexfunction_using_ex_c_wrong.cpp
#include "mex.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
int i, j, k;
double *i_c1;
double *i_c2;
// for struct variables(pointers) inside fcwcontext
mxArray *mx_b, *mx_c1, *mx_c2;
mx_b=mxGetField(prhs[0], 0, "b");
for(i = 0;i < 3;i=i+1)
{
mx_c1=mxGetField(mx_b, i, "c1");
mx_c2=mxGetField(mx_b, i, "c2");
i_c1=mxGetPr(mx_c1);
i_c2=mxGetPr(mx_c2);
*i_c2=(*i_c2)*10;
printf("address i_c1=%d i_c2=%d\n", i_c1, i_c2);
printf(" i_c1=%g i_c2=%g\n", *i_c1, *i_c2);
}
}
The following code is mexfunction_using_ex_c_correct.m
clc
clear all
close all
mex mexfunction_using_ex_correct.cpp;
a.b1(1)=double(1);
a.b1(2)=double(2);
a.b1(3)=double(3);
a.b2(1)=double(1);
a.b2(2)=double(2);
a.b2(3)=double(3);
mexfunction_using_ex_correct(a);
The following code is mexfunction_using_ex_c_correct.cpp
#include "mex.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
int i, j, k;
double *i_b1;
double *i_b2;
mxArray *mx_b1, *mx_b2;
mx_b1=mxGetField(prhs[0], 0, "b1");
mx_b2=mxGetField(prhs[0], 0, "b2");
for(i = 0;i < 3;i=i+1)
{
i_b1=mxGetPr(mx_b1);
i_b2=mxGetPr(mx_b2);
i_b2[i]=i_b2[i]*10;
printf("address i_b1=%d i_b2=%d\n", &i_b1[i], &i_b2[i]);
printf(" i_b1=%g i_b2=%g\n", i_b1[i], i_b2[i]);
}
}
The addresses are not "accidentally the same" - they're intentionally the same, due to MATLAB's internal copy-on-write optimisations. If you look at the MEX documentation, you'll see warnings scattered around...
Do not modify any prhs values in your MEX-file. Changing the data in these read-only mxArrays can produce undesired side effects.
...in various forms...
Note Inputs to a MEX-file are constant read-only mxArrays. Do not modify the inputs. Using mxSetCell* or mxSetField* functions to modify the cells or fields of a MATLAB® argument causes unpredictable results.
...trying to make it very clear that you should absolutely not modify anything you recieve as an input. By calling mxGetPr() on input data and writing back to that pointer as you do with i_b2 and i_c2, you're getting right into that "unpredictable results" territory - if you look at a.b(1).c1 in the MATLAB workspace after the call, it'll really be 10 even though you "only" changed c2.
From MEX, you're looking at the raw data storage without any knowledge of, or access to, MATLAB's internal housekeeping, so the only safe way to modify anything is to use the mxCreate* or mxDuplicate* functions to get your own safe arrays you can then do whatever you want with, and pass back to MATLAB via plhs.
That said, I will admit to having abused in-place modification for a significant performance gain in one instance where I could guarantee my data was unique and unshared, but it's at best unsupported and at worst downright perilous.

How to set jbytearray directly from file

I have the following native code that copies from a file into a buffer and then copies the
contents of that buffer into a jbytearray.
JNIEXPORT void JNICALL Java_com_test(JNIEnv * env, jobject){
int file_descriptor = 100;
JNIEnv * jni_env = env;
FILE* file = fdopen(file_descriptor, "r");
unsigned char* buffer;
int size_of_file = 1000000;
fread(buffer, 1, static_cast<size_t>(size_of_file), file);
imageArr = static_cast<jbyteArray>(jni_env->NewByteArray(static_cast<jsize> (size_of_file)));
jni_env->SetByteArrayRegion (imageArr, 0, static_cast<jsize>
(size_of_file ), (jbyte*)buffer);
}
As this code runs in a loop, I would like to optimize this as much as possible. Is there any way to directly read from the file to the jbyteArray? I am aware jbyteArray is a pointer to a struct. Is there any way to set the fields of this struct directly instead of using the setByteArrayRegion() function?
If not, is there any other function that I can use to read from a file to a jbytearray?
In short, no. You can probably do it, but it probably wont be much faster and if something with the implementation changed in the JVM your code would stop working. You are dealing with file I/O so I don't think SetByteArrayRegion is your real bottleneck here.

creating a bitmap image from existing bitmap, in C

I am writing a C program, which will retrieve the information (header information, pixel information) from a bitmap image, and use that information to create another bitmap image (the new image will obviously be same as the original).
The problem is that, in some cases, extra bytes get added (on their own) to the new image, due to which the image is not formed properly.
In another case, some bytes get missing in the new image, due to which image formation itself fails.
(This happens while writing the pixel information. the bitmap header information gets written properly to the new file.)
I have debugged the code but I couldn't find out what is causing this.
I'll be glad if somebody could tell me what the error is.
//creating a bitmap file
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
long extract(FILE *,long ,int );
long extract(FILE *fp1,long offset,int size)
{
unsigned char *ptr;
unsigned char temp='0';
long value=0L;
int i;
//to initialize the ptr
ptr=&temp;
//sets the file pointer at specific position i.e. after the offset
fseek(fp1,offset,SEEK_SET);
//now fgetcing (size) values starting from the offset
for(i=1;i<=size;i++)
{
fread(ptr,sizeof(char),1,fp1);
value=(long)(value+(*ptr)*(pow(256,(i-1)))); //combining the values one after another in a single variable
}
return value;
}
int main()
{
int row,col;
int i,j,k;
int dataoffset,offset;
char magicnum[2];
FILE *fp1,*fp4;
clrscr();
if((fp1=fopen("stripes.bmp","rb"))==NULL)
{
printf("\a\nCant open the image.\nSystem is exiting.");
exit(0);
}
if((fp4=fopen("op.bmp","a"))==NULL)
{
printf("\n\aError while creating a file.\nSystem is exiting ..... ");
exit(0);
}
fputc((int)extract(fp1,0L,1),fp4);
fputc((int)extract(fp1,1L,1),fp4);
fputc((int)extract(fp1,2L,1),fp4);
fputc((int)extract(fp1,3L,1),fp4);
fputc((int)extract(fp1,4L,1),fp4);
fputc((int)extract(fp1,5L,1),fp4);
fputc((int)extract(fp1,6L,1),fp4);
fputc((int)extract(fp1,7L,1),fp4);
fputc((int)extract(fp1,8L,1),fp4);
fputc((int)extract(fp1,9L,1),fp4);
fputc((int)extract(fp1,10L,1),fp4);
fputc((int)extract(fp1,11L,1),fp4);
fputc((int)extract(fp1,12L,1),fp4);
fputc((int)extract(fp1,13L,1),fp4);
fputc((int)extract(fp1,14L,1),fp4);
fputc((int)extract(fp1,15L,1),fp4);
fputc((int)extract(fp1,16L,1),fp4);
fputc((int)extract(fp1,17L,1),fp4);
fputc((int)extract(fp1,18L,1),fp4);
fputc((int)extract(fp1,19L,1),fp4);
fputc((int)extract(fp1,20L,1),fp4);
fputc((int)extract(fp1,21L,1),fp4);
fputc((int)extract(fp1,22L,1),fp4);
fputc((int)extract(fp1,23L,1),fp4);
fputc((int)extract(fp1,24L,1),fp4);
fputc((int)extract(fp1,25L,1),fp4);
fputc((int)extract(fp1,26L,1),fp4);
fputc((int)extract(fp1,27L,1),fp4);
fputc((int)extract(fp1,28L,1),fp4);
fputc((int)extract(fp1,29L,1),fp4);
fputc((int)extract(fp1,30L,1),fp4);
fputc((int)extract(fp1,31L,1),fp4);
fputc((int)extract(fp1,32L,1),fp4);
fputc((int)extract(fp1,33L,1),fp4);
fputc((int)extract(fp1,34L,1),fp4);
fputc((int)extract(fp1,35L,1),fp4);
fputc((int)extract(fp1,36L,1),fp4);
fputc((int)extract(fp1,37L,1),fp4);
fputc((int)extract(fp1,38L,1),fp4);
fputc((int)extract(fp1,39L,1),fp4);
fputc((int)extract(fp1,40L,1),fp4);
fputc((int)extract(fp1,41L,1),fp4);
fputc((int)extract(fp1,42L,1),fp4);
fputc((int)extract(fp1,43L,1),fp4);
fputc((int)extract(fp1,44L,1),fp4);
fputc((int)extract(fp1,45L,1),fp4);
fputc((int)extract(fp1,46L,1),fp4);
fputc((int)extract(fp1,47L,1),fp4);
fputc((int)extract(fp1,48L,1),fp4);
fputc((int)extract(fp1,49L,1),fp4);
fputc((int)extract(fp1,50L,1),fp4);
fputc((int)extract(fp1,51L,1),fp4);
fputc((int)extract(fp1,52L,1),fp4);
fputc((int)extract(fp1,53L,1),fp4);
//setting the file pointer at the beginning
rewind(fp1);
/*CHECKING WHETHER THE FILE IS IN BMP FORMAT OR NOT, WE CHECK THE MAGIC NUMBER OF THE FILE, MAGIC NUMBER'S OFFSET IS 0 i.e. IT'S STORED AT THE FRONT OF THE IMAGE, AND THE SIZE IS 2*/
//at first extracting the magic number
for(i=0;i<2;i++)
{
magicnum[i]=(char)extract(fp1,i,1);
}
//now checking
if((magicnum[0]=='B') && (magicnum[1]=='M'))
;
else
{
printf("\aThe image is not a bitmap image.\nSystem is exiting ... ");
exit(0);
}
//storing the header information
//get the starting position or offset of the data(pixel)
dataoffset=(int)extract(fp1,10,4);
//get the number of rows
row=(int)extract(fp1,22,4);
//get the number of columns
col=(int)extract(fp1,18,4);
//storing the data
offset=dataoffset;
for(j=0;j<col;j++)
{
for(k=0;k<row;k++)
{
for(i=0;i<=2;i++)
{
fputc((int)extract(fp1,offset++,1),fp4);
}
}
}
fcloseall();
return 0;
}
Make sure you open the output file in binary mode as well.
If you don't do that, the byte value corresponding to '\n' may be expanded to carriage return and line feed.
Consider this line:
value=(long)(value+(*ptr)*(pow(256,(i-1))));
pow is a floating point function returning a double. This means that (*ptr) is implicitly casted to double. The whole expression (value+(*ptr)*(pow(256,(i-1)))) will be a double. Now this can be larger than 2147483647 which is the largest number a long can hold (on most common 32-bit platforms), and the result when converting an out of range double to long is undefined. See what happens on this example:
#include <stdio.h>
int main(int argc, char **argv) {
int i;
for (i = 0; i < 10; i++) {
double d = 2147483647.0d + i;
printf("double=%f long=%ld\n", d, (long)d);
}
return 0;
}
Here is the output when I run it on my system: (hidden in case you want to guess or test it yourself first):
double=2147483647.000000 long=2147483647
double=2147483648.000000 long=-2147483648
double=2147483649.000000 long=-2147483648
double=2147483650.000000 long=-2147483648
double=2147483651.000000 long=-2147483648
double=2147483652.000000 long=-2147483648
double=2147483653.000000 long=-2147483648
double=2147483654.000000 long=-2147483648
double=2147483655.000000 long=-2147483648
double=2147483656.000000 long=-2147483648
One way to fix it would be to change it to unsigned long instead.
Personally I'd use 1 << (8*(i-1)) instead of pow to avoid messing with floating point, but there is lots of other things that I'd do very different too, but that is probably out of scope for this question (might be a question for the code review site).

Resources