我试图在C中编写一个生成随机整数的代码,执行简单的计算,然后我尝试在IEEE标准中打印文件的值。但我无法这样做,请帮助。
我无法以十六进制/二进制打印,这非常重要。
如果我在fprintf
中输入值,我会收到此错误expected expression before double
。
int main (int argc, char *argv) {
int limit = 20 ; double a[limit], b[limit]; //Inputs
double result[limit] ; int i , k ; //Outputs
printf("limit = %d", limit ); double q;
for (i= 0 ; i< limit;i++)
{
a[i]= rand();
b[i]= rand();
printf ("A= %x B = %x\n",a[i],b[i]);
}
char op;
printf("Enter the operand used : add,subtract,multiply,divide\n");
scanf ("%c", &op); switch (op) {
case '+': {
for (k= 0 ; k< limit ; k++)
{
result [k]= a[k] + b[k];
printf ("result= %f\n",result[k]);
}
}
break;
case '*': {
for (k= 0 ; k< limit ; k++)
{
result [k]= a[k] * b[k];
}
}
break;
case '/': {
for (k= 0 ; k< limit ; k++)
{
result [k]= a[k] / b[k];
}
}
break;
case '-': {
for (k= 0 ; k< limit ; k++)
{
result [k]= a[k] - b[k];
}
}
break; }
FILE *file; file = fopen("tb.txt","w"); for(k=0;k<limit;k++) {
fprintf (file,"%x\n
%x\n%x\n\n",double(a[k]),double(b[k]),double(result[k]) );
}
fclose(file); /*done!*/
}
答案 0 :(得分:3)
如果您的C编译器直接支持IEEE-754浮点格式(因为CPU支持它)或完全模拟它,您可以将doubles
简单地打印为字节。这就是x86 / 64平台的情况。
以下是一个例子:
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <float.h>
void PrintDoubleAsCBytes(double d, FILE* f)
{
unsigned char a[sizeof(d)];
unsigned i;
memcpy(a, &d, sizeof(d));
for (i = 0; i < sizeof(a); i++)
fprintf(f, "%0*X ", (CHAR_BIT + 3) / 4, a[i]);
}
int main(void)
{
PrintDoubleAsCBytes(0.0, stdout); puts("");
PrintDoubleAsCBytes(0.5, stdout); puts("");
PrintDoubleAsCBytes(1.0, stdout); puts("");
PrintDoubleAsCBytes(2.0, stdout); puts("");
PrintDoubleAsCBytes(-2.0, stdout); puts("");
PrintDoubleAsCBytes(DBL_MIN, stdout); puts("");
PrintDoubleAsCBytes(DBL_MAX, stdout); puts("");
PrintDoubleAsCBytes(INFINITY, stdout); puts("");
#ifdef NAN
PrintDoubleAsCBytes(NAN, stdout); puts("");
#endif
return 0;
}
输出(ideone):
00 00 00 00 00 00 00 00
00 00 00 00 00 00 E0 3F
00 00 00 00 00 00 F0 3F
00 00 00 00 00 00 00 40
00 00 00 00 00 00 00 C0
00 00 00 00 00 00 10 00
FF FF FF FF FF FF EF 7F
00 00 00 00 00 00 F0 7F
00 00 00 00 00 00 F8 7F
如果不直接支持IEEE-754,则问题会变得更加复杂。但是,它仍然可以解决。
以下是一些可以提供帮助的相关问题和答案:
当然,所有IEEE-754相关信息都可以在Wikipedia中找到。
答案 1 :(得分:1)
在你的fprint部分试试这个:
fprintf (file,"%x\n%x\n%x\n\n",*((int*)(&a[k])),*((int*)(&b[k])),*((int*)(&result[k])));
这会将double
转换为整数,因此它以IEEE标准打印。
但是如果你在32位机器上运行你的程序,int
是32位且double
是64位,我想你应该使用:
fprintf (file,"%x%x\n%x%x\n%x%x\n\n",*((int*)(&a[k])),*((int*)(&a[k])+1),*((int*)(&b[k])),*((int*)(&b[k])+1),*((int*)(&result[k])),*((int*)(&result[k])+1));
答案 2 :(得分:1)
在C中,有两种方法可以获取浮点值中的字节:指针强制转换或联合。我推荐一个工会。
我刚刚用GCC测试了这段代码并且有效:
#include <stdio.h>
typedef unsigned char BYTE;
int
main()
{
float f = 3.14f;
int i = sizeof(float) - 1;
BYTE *p = (BYTE *)(&f);
p[i] = p[i] | 0x80; // set the sign bit
printf("%f\n", f); // prints -3.140000
}
我们正在获取变量f
的地址,然后将其分配给指向BYTE(unsigned char)的指针。我们使用强制转换强制指针。
如果您尝试编译启用了优化的代码并执行上面显示的指针转换,则可能会遇到抱怨“类型错误指针”问题的编译器。我不确定你什么时候能做到这一点,什么时候做不到。但是你总是可以使用另一种方法来获取位:将float放入带有字节数组的并集中。
#include <stdio.h>
typedef unsigned char BYTE;
typedef union
{
float f;
BYTE b[sizeof(float)];
} UFLOAT;
int
main()
{
UFLOAT u;
int const i = sizeof(float) - 1;
u.f = 3.14f;
u.b[i] = u.b[i] | 0x80; // set the sign bit
printf("%f\n", u.f); // prints -3.140000
}
不工作肯定会尝试将浮点值直接转换为无符号整数或类似的东西。 C不知道您只想覆盖该类型,因此C尝试转换该值,从而导致舍入。
float f = 3.14;
unsigned int i = (unsigned int)f;
if (i == 3)
printf("yes\n"); // will print "yes"
P.S。在这里讨论“类型惩罚”指针:
Dereferencing type-punned pointer will break strict-aliasing rules