当输入大数字时,它将返回最终结果为NaN。

huangapple go评论59阅读模式
英文:

When inputting large numbers it returns the final result as NaN

问题

我正在为一个项目创建一个非常基本的C语言计算器。

/*
使用适当的数据类型声明和初始化变量和/或常量 -- X

从用户那里读取输入,并以有意义的方式向用户输出数据和信息 -- X

在表达式和计算中使用数学运算符 - 加法,减法,乘法,除法和模运算(余数) -- X

使用决策结构,如if,if/else和switch来影响程序流程 -- X

使用控制结构,如while,do-while和for循环来实现代码中的重复 -- X
*/
//所有的库
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>

float num1 = 0;
float num2 = 0;
float finalResult = 0;
char operator = '+';
bool opReal = false;

int main() {
    //请求第一个数字
    printf("输入一个数字:");
    scanf("%f", &num1);
    printf("\n");

    //请求第二个数字
    printf("再输入一个数字:");
    scanf("%f", &num2);
    printf("\n");
    //请求操作符
    do {
        printf("输入+、-、*或/:");
        scanf(" %c", &operator);
        //检查操作符是什么
        if (operator == '-') {
            operator = '-';
            opReal = true;
        } else if (operator == '+') {
            operator = '+';
            opReal = true;
        } else if (operator == '*') {
            operator = '*';
            opReal = true;
        } else if (operator == '/') {
            operator = '/';
            opReal = true;
        } else {
            operator = '+';
            opReal = false;
        }
    } while (!opReal);
    printf("num1:%f\n", num1);
    printf("num2:%f\n", num2);
    printf("操作符:%c\n");
    //进行计算
    if (operator == '-') {
        finalResult = num1 - num2;
    } else if (operator == '+') {
        finalResult = num1 + num2;
    } else if (operator == '*') {
        finalResult = num1 * num2;
    } else if (operator == '/') {
        finalResult = num1 / num2;
    }
    printf("最终结果:%f\n", finalResult);
}

我尝试了不同的解决方案,应用了不同的方法来操作num1和num2,但最终它们都不起作用。
它应该接受num1和num2,并对其应用操作符。
但是,当应用一个大数时,num1 = inf,num2 = inf。
这反过来使finalResult成为NaN。
发生了什么?
请帮忙。

英文:

I am creating a SUPER basic calculator in C for a project.

/*
Declare and initialize variables and/or constants using appropriate data types -- X
Read in input from the user and output data &amp; information to the user in a meaningful manner -- X
Use the mathematical operators – addition, subtraction, multiplication, division, and modulus (remainder) 
– in expressions and calculations -- X
Use decision making structures such as if, if/else, and switch to affect program flow -- X
Use control structures such a while, do-while, and for loops to implement repetition in code -- X
*/
//All libraries
#include &lt;stdio.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;ctype.h&gt;
float num1 = 0; 
float num2 = 0;
float finalResult = 0;
char operator = &#39;+&#39;;
bool opReal = false;
int main() {
//Ask for first number
printf(&quot;Enter an number: &quot;);
scanf(&quot;%f&quot;, &amp;num1); 
printf(&quot;\n&quot;);
//Ask for second number
printf(&quot;Enter another number: &quot;);
scanf(&quot;%f&quot;, &amp;num2);
printf(&quot;\n&quot;);
//Ask for operator
do {
printf(&quot;Enter either + - * or /: &quot;);
scanf(&quot; %c&quot;, &amp;operator);
//Check for what operator is
if (operator == &#39;-&#39;) {
operator = &#39;-&#39;;
opReal = true;
} else if (operator == &#39;+&#39;) {
operator = &#39;+&#39;;
opReal = true;
} else if (operator == &#39;*&#39;) {
operator = &#39;*&#39;;
opReal = true;
} else if (operator == &#39;/&#39;) {
operator = &#39;/&#39;;
opReal = true;
} else {
operator = &#39;+&#39;;
opReal = false;
}
} while (!opReal);
printf(&quot;num1: %f\n&quot;, num1);
printf(&quot;num2: %f\n&quot;, num2);
printf(&quot;operator: %c\n&quot;, operator);
//Do calculations
if (operator == &#39;-&#39;) {
finalResult = num1 - num2;
} else if (operator == &#39;+&#39;) {
finalResult = num1 + num2;
} else if (operator == &#39;*&#39;) {
finalResult = num1 * num2;
} else if (operator == &#39;/&#39;) {
finalResult = num1 / num2;
} 
printf(&quot;Final Result: %f\n&quot;, finalResult);
}

I've tried looking up different solutions and applying different ways to operate on num1 and 2, but in the end they don't work.
It should take num1 and num2 and apply operator to it.
However when a large number is applied then num1 = inf and num2 = inf.
That in turn makes finalResult Nan
Whats happening?
Please help.

答案1

得分: 0

以下是您要翻译的代码部分:

I don't see anything particular wrong with your code so maybe you just need to switch from float to double or even long double? Don't use global variable unless you have to. Guard against divide by zero. No point of checking if an operator is x then assign x to the operator. Check that scanf() was successful otherwise you may be operating on uninitialized data.

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

int main() {
    double num1;
    printf("Enter a number: ");
    if (scanf("%lf", &num1) != 1) {
        printf("scanf failed\n");
        return 1;
    }

    double num2;
    printf("Enter another number: ");
    if (scanf("%lf", &num2) != 1) {
        printf("scanf failed\n");
        return 1;
    }

    char operator;
    do {
        printf("Enter either + - * or /: ");
        if (scanf(" %c", &operator) != 1) {
            printf("scanf failed\n");
            return 1;
        }
    } while (!strchr("-+*/", operator));

    double finalResult = 0;
    if (operator == '-') {
        finalResult = num1 - num2;
    } else if (operator == '+') {
        finalResult = num1 + num2;
    } else if (operator == '*') {
        finalResult = num1 * num2;
    } else if (operator == '/') {
        finalResult = num2 != 0 ? num1 / num2 : 0; // or ERR?
    }
    printf("Final Result: %lf\n", finalResult);
}

I would use an array of numbers, dedup the input with a loop and probably a switch instead of all those if-else-if:

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define NUM_LEN 2

int main() {
    const char *prompts[NUM_LEN] = { "an", "another" };
    double num[NUM_LEN];
    for (size_t i = 0; i < NUM_LEN; i++) {
        printf("Enter %s number: ", prompts[i]);
        if (scanf("%lf", &num[i]) != 1) {
            printf("scanf failed\n");
            return 1;
        }
    }

    char operator;
    do {
        printf("Enter either + - * or /: ");
        if (scanf(" %c", &operator) != 1) {
            printf("scanf failed\n");
            return 1;
        }
    } while (!strchr("-+*/", operator));

    switch (operator) {
        case '-':
            num[0] -= num[1];
            break;
        case '+':
            num[0] += num[1];
            break;
        case '*':
            num[0] *= num[1];
            break;
        case '/':
            num[0] = num[1] != 0 ? num[0] / num[1] : 0; // or ERR?
            break;
        default:
            printf("Invalid operator\n");
            break;
    }
    printf("Final Result: %lf\n", num[0]);
}

The next step would be to build a map from operator to a function, i.e:

struct operators {
    char operator;
    int (*evaluate)(double *num);
} operators[] = {
    {'+', add},
    {'-', subtract},
    {'*', multiply},
    {'/', divide}
};

Now you extract the valid operators used in strchr() from this map, and you can use lfind() to lookup the evaluate function for a given operator.

英文:

I don't see anything particular wrong with your code so maybe you just need to switch from float to double or even long double? Don't use global variable unless you have to. Guard against divide by zero. No point of checking if an operator is x then assign x to the operator. Check that scanf() was successful otherwise you may be operating on uninitialized data.

#include &lt;stdbool.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
int main() {
double num1;
printf(&quot;Enter a number: &quot;);
if(scanf(&quot;%lf&quot;, &amp;num1) != 1) {
printf(&quot;scanf failed\n&quot;);
return 1;
}
double num2;
printf(&quot;Enter another number: &quot;);
if(scanf(&quot;%lf&quot;, &amp;num2) != 1) {
printf(&quot;scanf failed\n&quot;);
return 1;
}
char operator;
do {
printf(&quot;Enter either + - * or /: &quot;);
if(scanf(&quot; %c&quot;, &amp;operator) != 1) {
printf(&quot;scanf failed\n&quot;);
return 1;
}
} while (!strchr(&quot;-+*/&quot;, operator));
double finalResult = 0;
if (operator == &#39;-&#39;) {
finalResult = num1 - num2;
} else if (operator == &#39;+&#39;) {
finalResult = num1 + num2;
} else if (operator == &#39;*&#39;) {
finalResult = num1 * num2;
} else if (operator == &#39;/&#39;) {
finalResult = num2 != 0 ? num1 / num2 : 0; // or ERR?
}
printf(&quot;Final Result: %lf\n&quot;, finalResult);
}

I would use an array of numbers, dedup the input with a loop and probably a switch instead of all those if-else-if:

#include &lt;stdbool.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#define NUM_LEN 2
int main() {
const char *prompts[NUM_LEN] = { &quot;an&quot;, &quot;another&quot; };
double num[NUM_LEN];
for(size_t i = 0; i &lt; NUM_LEN; i++) {
printf(&quot;Enter %s number: &quot;, prompts[i]);
if(scanf(&quot;%lf&quot;, &amp;num[i]) != 1) {
printf(&quot;scanf failed\n&quot;);
return 1;
}
}
char operator;
do {
printf(&quot;Enter either + - * or /: &quot;);
if(scanf(&quot; %c&quot;, &amp;operator) != 1) {
printf(&quot;scanf failed\n&quot;);
return 1;
}
} while (!strchr(&quot;-+*/&quot;, operator));
switch(operator) {
case &#39;-&#39;:
num[0] -= num[1];
break;
case &#39;+&#39;:
num[0] += num[1];
break;
case &#39;*&#39;:
num[0] *= num[1];
break;
case &#39;/&#39;:
num[0] = num[1] != 0 ? num[0] / num[1] : 0; // or ERR?
break;
default:
printf(&quot;Invalid operator\n&quot;);
break;
}
printf(&quot;Final Result: %lf\n&quot;, num[0]);
}

The next step would be to build a map from operator to a function, i.e:

struct operators {
char operator;
int (*evaluate)(double *num);
} operators[] = {
{&#39;+&#39;, add},
{&#39;-&#39;, subtract},
{&#39;*&#39;, multiply},
{&#39;/&#39;, divide}
};

Now you extract the valid operators used in strchr() from this map, and you can use lfind() to lookup the evaluate function for a given operator.

答案2

得分: 0

你可以尝试将“float”替换为“double”,具体取决于这些大数的大小,这样可能会起作用。

此外,您可以将以下检查添加到您的代码中:

    if(isinf(num1) || isinf(num2) || isnan(num1) || isnan(num2)) {
        printf("错误,数值超出范围!");
        return -1;
    }

尽管这需要使用#include <math.h>,但如果您只能使用此文件中指定的库(可能由注释暗示),那么这可能是一个无法解决的问题。

英文:

Well depending on how large those large numbers are, you might just be able to replace "float" with "double" and have it work.

Other than that you could add the following check to your code:

    if(isinf(num1) || isinf(num2) || isnan(num1) || isnan(num2)) {
        printf(&quot;Error, number out of bounds!&quot;);
        return -1;
    }

Though this requires the use of #include &lt;math.h&gt; though, if you are constrained to just the libraries specified in this file (as might be implied by the comment) then this might just be an unsolvable problem.

huangapple
  • 本文由 发表于 2023年2月10日 10:14:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定