问题描述
我是野牛和 flex 的新手。我分配浮点值假设 a=12.34 。但是当我打印值时我发现 12.000000。请帮助我。提前致谢。lex 文件 ruturn 浮点值很好。我打印了值在代码的不同位置,那没问题。但是当在变量中分配值时就会出现问题,然后将小数点后的值替换为).
这是我的野牛文件
/*C declarations (types,variables,functions,preprocessor commands)*/
%{
#include<stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <string.h>
# include <math.h>
int yylex(void);
int check[100],int_val[1000],var_type[1000];
float float_val[1000];
char char_val[1000];
int caseD,caseV;
%}
/* Bison declarations (grammar symbols,operator precedence decl.,attribute data type) */
%error-verbose
%union{
int intVal;
char* variable;
char* strVal;
float floatVal;
char charVal;
}
%token Begin INTEGER FLOAT CHAR END COLON SEMICOLON ASSIGN COMMA FORWARD_ARROW SHOW
%token BACKWARD_ARROW TAKE PLUS SUB MULT DIV MOD OTB CTB POW SIN COS TAN LOG LOG10 OP CP
%token LESS_THAN GREATER_THAN LESS_EQUAL GREATER_EQUAL IF ELSE_IF ELSE EQUAL NOT_EQUAL INC
%token DEC FOR IN FOR_INC FOR_DEC EVEN_ODD FACTORIAL SUM GCD LCM SWITCH
%token DEFAULT WHILE OSB CSB
%token<intVal>INT_VAL
%token<floatVal>FLOAT_VAL
%token<charVal>CHAR_VAL
%token<intVal>VARIABLE
%token<strVal>STRING_VAL
%type<intVal>expression statements cdeclare condition cstatements number
%%
program:Begin COLON cstatements END {printf("\n\t\t\t\t\tCompilation Done Succesfully!!!\n");
}
;
cstatements:/* Empty */ {}
|SEMICOLON {printf("\n\t\t\t\tEmpty statement\n");}
|cstatements cdeclare SEMICOLON
|cstatements statements
;
cdeclare:FLOAT float_id {}
;
float_id:float_id1 COMMA float_id
|float_id1
;
float_id1:VARIABLE {
if(check[$1]==1)
{
printf("\n\t\t\t\tCompilation error-> %c is redeclared \n",$1+97);
}
else{
var_type[$1]=1;
check[$1]=1;
printf("\n\t\t\t\t%c is declared successfully\n",$1+97);
}
}
|VARIABLE ASSIGN expression {
if(check[$1]==1)
{
printf("\n\t\t\t\tCompilation error-> %c is redeclared \n",$1+97);
}
else{
var_type[$1]=1;
check[$1]=1;
float_val[$1]=$3;
printf("\n\t\t\t\t%c is declared and assigned by %f successfully\n",$1+97,(float)($3));
}
}
;
statements:SHOW FORWARD_ARROW VARIABLE SEMICOLON {
if(check[$3] == 1)
{
if(var_type[$3]==0)
printf("\n\t\t\t\tValue of %c is: %d\n",$3+97,int_val[$3]);
else if(var_type[$3]==1)
printf("\n\t\t\t\tValue of %c is: %f\n",float_val[$3]);
else if(var_type[$3]==2)
printf("\n\t\t\t\tValue of %c is: %c\n",char_val[$3]);
}
else
{
printf("\n\t\t\t\tCompilation error-> %c was not declared\n",$3+97);
}
}
|VARIABLE ASSIGN expression SEMICOLON {
if(check[$1] == 1)
{
if(var_type[$1]==0)
{
int_val[$1]=$3;
printf("\n\t\t\t\t%c is assigned by %d successfully\n",$3);
}
else if(var_type[$1]==1)
{
float_val[$1]=$3;
printf("\n\t\t\t\t%c is assigned by %f successfully\n",(float)($3));
}
else if(var_type[$1]==2)
{
float_val[$1]=$3;
printf("\n\t\t\t\t%c is assigned by %c successfully\n",$3);
}
}
else
{
printf("\n\t\tCompilation error-> %c was not declared\n",$1+97);
}
}
;
expression: number{ $$ = $1;
//printf("%f\n",$1);
}
number:INT_VAL {$$=$1;}
|FLOAT_VAL {$$=$1;
//printf("%f\n",$1);
}
|CHAR_VAL {$$=$1;}
;
%%
int yywrap(){
return 1;
}
int yyerror(char *s)
{
fprintf(stderr,"%s\n",s);
}
int main()
{
freopen("input.txt","r",stdin);
yyparse();
}
如果我给 m_float a:=12.45.那么输出应该是 12.45.但是程序给了我 12.000000.
解决方法
您已声明
%type<intVal>expression … number
因此,当您从 number
创建 FLOAT_VAL
时,会将其转换为整数。但是您的所有变量都是浮点数,因此您稍后将此整数存储为浮点数。效果真的跟下面没什么区别:
float value = 12.45;
int number = value;
int expr = number;
float a = expr:
printf("a = %f\n",a);
我希望原因很明显
该 C 片段将打印出 a = 12.000000
。
创建具有多种数据类型的计算器并不容易。您不能使用简单的 C 原始类型来保存可能是各种不同类型之一的内容。你需要某种有区别的联合,这需要做更多的工作
一个常见的解决方案(例如由 JavaScript 使用)是使用 double
作为唯一的数字类型。 (通常,您应该使用 double
而不是 float
;float
对于许多计算来说不够准确。)double
可以精确地表示任何 32 位整数值,因此使用 double
保存整数不会丢失任何精度。
不过,这对字符串类型的表达式没有帮助。如果你想要多种数据类型,你肯定需要一个可区分的联合类型。
在典型平台上,double
的精度为 53 位,因此您可以使用比 int
能容纳的稍大的整数,但不能大到 long long
能容纳的程度。有时,您确实需要 64 位整数。如果是这样,那么唯一的解决方案是区分联合类型。