繁体   English   中英

从二进制文件读取并转换为两倍?

[英]Reading from binary file and converting to double?

我试图编写一个读取二进制文件并将其转换为数据类型的C程序。 我正在使用头命令head -c 40000 /dev/urandom > data40.bin生成一个二进制文件。 该程序适用于int和char数据类型,但不能执行double。 这是程序的代码。

void double_funct(int readFrom, int writeTo){
    double buffer[150];
    int a = read(readFrom,buffer,sizeof(double));
    while(a!=0){
        int size = 1;
        int c=0;

         for(c=0;c<size;c++){
            char temp[100];
            int x = snprintf(temp,100,"%f ", buffer[c]);
            write(writeTo, temp, x);
        }
        a = read(readFrom,buffer,sizeof(double));
    }
}

这是有效的char函数

void char_funct(int readFrom, int writeTo){
    char buffer[150];
    int a = read(readFrom,buffer,sizeof(char));
    while(a!=0){
        int size = 1;
        int c=0;

        for(c=0;c<size;c++){
            char temp[100]=" ";
            snprintf(temp,100,"%d ", buffer[c]);
            write(writeTo, temp, strlen(temp));
        }
        a = read(readFrom,buffer,sizeof(char));
    }
}

问题是使用char我需要用wc -w file获取40000个单词,然后我将它们获取。 现在有了double我得到了随机的单词数量,但是理论上我应该从40000字节的数据中得到5000,但是我得到4000到15000之间的随机数,对于char我得到40000,就像它应该为一个字符提供1个字节。

我不知道这是什么错误,相同的代码适用于int ,我从40000字节的数据中获得10000个单词。

主要问题似乎是您的temp数组不足以容纳您的printf格式和数据。 IEEE-754 double的十进制指数范围为-308至+308。 您正在以"%f"格式打印双打,这将产生纯十进制表示形式。 由于未指定精度,因此默认精度为6。 这可能需要多达1(符号)+ 309(数字)+1(小数点)+6(尾随小数位)+1(终止符)字符(共318个),但是您只能容纳100个空间。

您使用snprintf()打印到缓冲区,因此不会超出那里的数组范围,但是snprintf()返回的是所需的字节数,减去终止符所需的字节数。 那是您write()的字节数,并且在许多情况下确实会超出缓冲区。 您会在输出中看到结果。

其次,您还会在输出中看到大量的0.00000 ,这是因为将小数舍入到6进制的精度。

如果更改打印数字的格式,可能会获得更好的成功。 例如, "%.16e "将为您提供指数格式的输出,总共有17个有效数字(小数点前一位)。 这将不需要在内存或磁盘上占用过多的空间,并且它将准确地传递所有数字,而不管其规模如何,再次假设您的double是按照IEEE 754表示的。如果您愿意,还可以消除(非常安全的)假设通过使用@chux在注释中建议的变体来更改IEEE 754格式。 那将是最安全的方法。

还有一件事:IEEE浮点支持无限性和多个非数字值。 与普通FP编号相比,这些编号的数量很少,但是您偶尔还是会碰到其中之一。 它们可能会被转换为输出,但是您可能要考虑是否需要专门处理它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM