"Chris M. Thomasson" <inv...@invalid.invalid> writes:
I won't say crap but I do have some suggestions.
In several places you have variable names ending in '_size' that
are not sizes. I suggest '_limit' or '_extent' instead.
The symbol CT_OFL is used two times in each of three places,
always in the same pattern. The common pattern can be factored,
eg,
#define CT_PAIR "(" CT_OFL ", " CT_OFL ")"
which will simplify the printf()/fprintf() calls that use it.
Probably the most important suggestion: ou can make the code a
lot simpler if you use a union for the complex values, as for
example
typedef { double complex z; double d[2]; } ct_complex;
See how this change simplifies the load/store routines:
void
ct_load_ctxt( FILE* in_file, ct_complex* buf, size_t buf_extent ){
printf( "LOAD:\n" );
for( size_t i = 0; i < buf_extent; ++i ){
int r = fscanf( in_file, "(%lf, %lf) ", &buf[i].d[0], &buf[i].d[1] );
if( r != 2 ) break;
printf( "%zu:" CT_PAIR "\n", i, buf[i].d[0], buf[i].d[1] );
}
}
void
ct_store_ctxt( FILE* out_file, ct_complex* buf, size_t buf_extent ){
printf( "STORE:\n" );
for( size_t i = 0; i < buf_extent; ++i ){
fprintf( out_file, CT_PAIR " ", buf[i].d[0], buf[i].d[1] );
printf( "%zu:" CT_PAIR "\n", i, buf[i].d[0], buf[i].d[1] );
}
}
To put your mind at ease, the overlap of the two doubles and the
complex type is guaranteed by the Standard.
Incidentally, having that union type means you can define the 'I'
macro yourself if you want:
#define I ((ct_complex){ .d = { 0, 1 } }.z)
Putting all that together, plus a couple other minor items, here
is the resulting revised full program:
#include <stdio.h>
#define CT_PREC ".13"
#define CT_OFL "%" CT_PREC "lf"
#define CT_PAIR "(" CT_OFL ", " CT_OFL ")"
typedef union { _Complex double z; double d[2]; } ct_complex;
#define I ((ct_complex){ .d = { 0, 1 } }.z)
void
ct_load_ctxt( FILE* in_file, ct_complex* buf, size_t buf_extent ){
printf( "LOAD:\n" );
for( size_t i = 0; i < buf_extent; ++i ){
int r = fscanf( in_file, "(%lf, %lf) ", &buf[i].d[0], &buf[i].d[1] );
if( r != 2 ) break;
printf( "%zu:" CT_PAIR "\n", i, buf[i].d[0], buf[i].d[1] );
}
}
void
ct_store_ctxt( FILE* out_file, ct_complex* buf, size_t buf_extent ){
printf( "STORE:\n" );
for( size_t i = 0; i < buf_extent; ++i ){
fprintf( out_file, CT_PAIR " ", buf[i].d[0], buf[i].d[1] );
printf( "%zu:" CT_PAIR "\n", i, buf[i].d[0], buf[i].d[1] );
}
}
void
store_complex_array( size_t n, ct_complex buf[n], const char *filename ){
FILE* fout = fopen( filename, "w" );
ct_store_ctxt( fout, buf, n );
fclose( fout );
}
void
load_complex_array( size_t n, ct_complex buf[n], const char *filename ){
FILE* fin = fopen( filename, "r" );
ct_load_ctxt( fin, buf, n );
fclose( fin );
}
int
main( void ){
char const* in_file = "/tmp/ctxt.bin";
ct_complex ct[] = {
-2.123 + 4.56789*I,
2.456 - 4.876*I,
-2.789 + 4.543*I,
2.101112 - 4.210*I,
123.456 + 789.101113*I
};
size_t ct_extent = sizeof(ct) / sizeof(ct_complex);
store_complex_array( ct_extent, ct, in_file );
printf( "________________________________\n" );
load_complex_array( ct_extent, ct, in_file );
return 0;
}