我有一个C二进制文件,其中包含512个 3 值,其形式为三维立方体。我需要访问具有最高值的立方体中的位置,即密度。一旦我获得了最高值的位置,我需要在这个位置创建一个较小的3D立方体,其值明显小于512(立方体的尺寸)。 start
表示较小立方体一角的位置。 p
显然是二进制文件。
fseek(p,0,SEEK_END);
lSize = ftell(p);
rewind(p);
dim = pow(lSize/sizeof(float),1.0/3.0);
printf("File size: %lu bytes, Grid size: %d \n", lSize,(int)dim);
max = 0;
counter = 0;
index = 0;
while(fread(&density,sizeof(float),1,p),!feof(p) && !ferror(p)) {
if(density > max) max = density,index = counter;
counter += 1;
}
sub = 256;
start = index - (pow(dim,2)+dim+1)*(sub/2-1);
printf("3d coordinates of highest density: %lu,%lu,%lu, Dimension of cube: %d\n",index % 512;(index / 512) % 512;index / (512 * 512),(int)dim);
printf("The maximum density is: %e with index: %lu \n", max,index);
rewind(p);
fseek(p,start*sizeof(float),SEEK_SET);
fseek(q,start*sizeof(float),SEEK_SET);
fseek(r,start*sizeof(float),SEEK_SET);
fseek(s,start*sizeof(float),SEEK_SET);
fseek(t,start*sizeof(float),SEEK_SET);
u = fopen("results_dens.dat", "w");
if (u == NULL) { printf("Unable to open output results file!"); exit(1); }
for (ibox=0;ibox<nbox;ibox++){
for (k=0;k<nz[ibox];k++){
fseek(p,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(q,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(r,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(s,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(t,(start+k*dim*dim)*sizeof(float),SEEK_SET);
for (j=0;j<ny[ibox];j++){
fseek(p,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(q,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(r,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(s,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(t,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
for (i=0;i<nx[ibox];i++){
我知道上面的代码运行没有任何错误。但是,很多都依赖于index
以上的价值。我不确定如何在C中定义位置。我知道这些是内存位置,但通过做一些粗略计算,我得到的索引值似乎接近框的边缘而不是中心。
512 3 = 134217728。
index
的值是66978048,中间位置值为67108864,位置为130816.但是,130816大约为512 * 256,这意味着如果网格的中间位置位于框的边缘,那么{ {1}}以上。
答案 0 :(得分:3)
也许这会有所帮助。首先,我使用以下程序创建了一个测试文件:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int makeCube(const char *fn, int dim)
{
FILE *p;
const int center = dim/2;
p = fopen(fn,"w");
for (int i=0; i < dim; ++i)
for (int j=0; j < dim; ++j)
for (int k=0; k < dim; ++k) {
float f = dim - sqrtf(pow(i-center,2)+
pow(j-center,2)+pow(k-center,2));
fwrite(&f, sizeof(float), 1, p);
}
fclose(p);
return 0;
}
int main()
{
const int dim = 512;
makeCube("cube.bin", dim);
return 0;
}
接下来,我重写了您的代码以获得正确的语法并打印一些看似有用的诊断:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int subCube(FILE *p, int dim)
{
float density;
float max = 0;
long index = 0;
long counter;
for (counter=0; fread(&density,sizeof(float),1,p); ++counter) {
if(density > max) {
max = density;
index = counter;
}
}
printf("The maximum density is: %e with index: %lu \n", max,index);
int i = index/dim/dim;
int j = (index - (i*dim*dim))/dim;
int k = (index - ((i*dim)+j)*dim);
printf("This corresponds to coordinates (%d,%d,%d)\n", i,j,k);
}
int main()
{
const int dim = 512;
FILE *p = fopen("cube.bin","r");
subCube(p, dim);
fclose(p);
return 0;
}
当我运行该程序时,我得到以下输出:
The maximum density is: 5.120000e+02 with index: 67240192
This corresponds to coordinates (256,256,256)
由于测试数据基本上是中间密度最大的球体,因此完全符合预期。
请注意,由于错误处理,我玩得很快(没有!)但是为了清楚起见省略了它,而不是因为你应该在实际程序中省略它。