In cs5's week 2 hours practice problem, the code correctly gives the total hours spent, but it truncates the average hours per week despite using float. Where am I going wrong?
在中五的S周两小时练习题中,代码正确地给出了总课时,但尽管使用了浮动,它还是截断了每周的平均课时。我哪里错了?
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
float calc_hours(int hours[], int weeks, char output);
int main(void)
{
int weeks = get_int("Number of weeks taking CS50: ");
int hours[weeks];
for (int i = 0; i < weeks; i++)
{
hours[i] = get_int("Week %i HW Hours: ", i);
}
char output;
do
{
output = toupper(get_char("Enter T for total hours, A for average hours per week: "));
}
while (output != 'T' && output != 'A');
printf("%.1f hours\n", calc_hours(hours, weeks, output));
}
// TODO: complete the calc_hours function
float calc_hours(int hours[], int weeks, char output)
{
int tot = 0;
for (int i = 0; i < weeks; i++)
{
tot = hours[i] + tot;
}
if (output == 'T')
{
return (float) tot;
}
return (float) (tot / weeks);
}
I typed in the weeks and hours spent per week when prompted and typed in A to get average of hours spent per week, but it only outputs an integer value instead of a float.
当出现提示并输入A时,我输入了每周花费的周和小时数,但它只输出一个整数值,而不是浮点数。
更多回答
tot / weeks
performs integer division, the result of which you then cast to float
.
Tot/Week执行整数除法,然后将结果强制转换为浮点数。
return (float) tot / weeks;
You need to cast one of the operands, not the result after the integer division has already happened.
返回(浮点数)tot/Week;您需要对其中一个操作数进行强制转换,而不是整数除法后的结果。
Or, change: int tot = 0;
to float tot = 0;
, and get rid of the dangerous casting... (Does CS50 library have get_float()
? Did you ever invest 8.5 hrs during one week?
或者,将:int tot=0;更改为浮动tot=0;,并删除危险的强制转换...(CS50库是否有Get_Float()?你有没有在一周内投入8.5个小时?
Retired Ninja is right, and changing tot to float worked @Fe2O3 ! Yes using get_float would make sense but I'm not supposed to edit the main function for this problem.
退役忍者是对的,把TOT改成FLOAT工作了@Fe2O3!是的,使用GET_FLOAT是有意义的,但是我不应该为这个问题编辑Main函数。
Bonus points for not using else
in your function! Earn more by figuring out how to have only one return
statement in that function... (Hint: tot
is a local variable that can be made to serve your purposes...)
在您的函数中不使用Else的加分!通过弄清楚如何在该函数中只有一条返回语句来获得更多...(提示:TOT是一个局部变量,可用于您的目的...)
优秀答案推荐
Problem:
问题:
(float) (tot / weeks)
"Where am I going wrong?" As noted, integer division (with truncation) is occurring within the parentheses, before the quotient is cast to float
.
“我哪里错了?”正如前面提到的,整数除法(带截断)在圆括号内进行,然后将商强制转换为浮点数。
The simplest solution is to define the variable that will be returned from the float
function to be a float
itself:
最简单的解决方案是将从Float函数返回的变量定义为Float本身:
float calc_hours( int hours[], int weeks, char output ) {
float tot = 0.0;
for( int i = 0; i < weeks; i++ )
tot += hours[ i ];
if( output == 'T' )
return tot; // no casting required
if( weeks == 0 ) {
printf( "Division by zero is not defined\n" );
return -1; // something. Maybe sqrt( -1 ); :-)
}
return tot / weeks; // will be 'float' calculation, not integer
}
May as well learn the gotcha now and try to avoid having it bite you later.
不妨现在就了解其中的要害,并尽量避免以后被它咬到。
EDIT
Just thought! A float
is limited to ~7 digits of precision, while a 32bit int
ranges up to just above 9 digits. If tot
is expected to be greater than 999,999
, this function may not produce accurate results.
编辑刚想到的!浮点数的精度被限制为~7位,而32位整型的精度最高可达9位以上。如果TOT预期大于999,999,则此函数可能不会产生准确的结果。
As noted in comments, you are casting the result of integer division to float
.
正如注释中所指出的,您将整数除法的结果强制转换为浮点数。
(float) (tot / weeks)
You need to cast one of the operands to /
to float
first to perform floating point math.
要执行浮点运算,您需要先将其中一个操作数强制转换为浮点数。
(float)tot / weeks
As mentioned by others, code is doing an integer division with an integer quotient. To achieve a floating point quotient, use floating-point math.
正如其他人所提到的,代码正在用整数商进行整数除法。若要获得浮点商,请使用浮点数学。
Also, avoid overflow when adding up the integer values.
此外,在将整数值相加时避免溢出。
Using integer math to perform the summation is good and efficient. Using a float
sum readily risks rounding issues if used to sum the int
s when hours[]
is large.
使用整数数学来执行求和很好,而且效率很高。如果在小时数[]很大的情况下对整数求和,则使用浮点求和很容易出现舍入问题。
In C, consider double
for typical floating-point math and save float
for select cases where the limited precision and range are specifically needed. Note that printf("%.1f hours\n", calc_hours(hours, weeks, output));
converts the float
return value from calc_hours()
to double
before passing the argument to the printf(...)
function.
在C语言中,对于典型的浮点运算,考虑使用DOUBLE,而对于特别需要有限精度和范围的特定情况,则保存FLOAT。请注意,在将参数传递给printf(...)之前,printf(“%.1f HUTHERS\n”,CALC_HOURS(小时,周,输出));将浮点返回值从CALC_HOURS()转换为DOUBLE功能。
// Alternative
double calc_hours(const int hours[], int weeks, char output) {
long tot = 0; // or long long tot
for (int i = 0; i < weeks; i++) {
tot = hours[i] + tot;
}
if (output == 'T') {
return (double) tot;
}
return (double) tot / weeks;
}
- Advanced: use
size_t
for array sizing.
double calc_hours(const int hours[], size_t weeks, char output) {
更多回答
我是一名优秀的程序员,十分优秀!