2

这让我大吃一惊。我有这个类具有以下属性:

public IEnumerable<QuestionModel> Questions { get; set; }

public int TotalQuestions
{
    get
    {
        return Questions.Count();
    }
}

public int TotalCorrect
{
    get
    {
        return Questions.Count( x => x.Correct );
    }
}

public int Score
{
    get
    {
        return ( TotalCorrect / TotalQuestions ) * 100;
    }
}

以下是我在控制器中创建模型的方法:

var model = new QuizModel
    {
        Questions = new List<QuestionModel>
            {
                new QuestionModel
                    {
                        Correct = true
                    },
                new QuestionModel
                    {
                        Correct = false
                    }
            }
    };

TotalQuestions 等于 2。TotalCorrect 等于 1。但 Score 始终为 0。

我想也许分数是在设置其他属性之前设置的,所以我尝试了这个:

public int Score()
{
    return ( TotalCorrect / TotalQuestions ) * 100;
}

我认为这会起作用,因为当我在视图中调用 Score() 时,肯定会设置其他属性。但它只返回 0。

我还尝试将 IEnumerable 更改为 IList。那里没有运气。

4

3 回答 3

13

这让我大吃一惊。

老兄。寒意。都很好。

TotalQuestions 等于 2。TotalCorrect 等于 1。但 Score 始终为 0。

好吧,你自己算算。哪个整数最接近 1 / 2,向零舍入?显然为零。0乘以100等于多少?显然为零。所以答案是零。

问题是您使用的是全整数算术。整数除法四舍五入到最接近的整数,在您的方案中始终为零 - 除非正确答案的数量完全等于问题的总数,在这种情况下它是一。

为了解决这个问题,这里有两种技术,

首先,您可以先乘以 100 ,然后再进行除法。

return ( 100 * TotalCorrect )  / TotalQuestions;

现在我们将 100 乘以 1,得到 100,然后除以 2,得到 50,完成。

或者您可以将其中一个整数转换为小数,以小数进行计算,然后在最后将其转换回整数:

public int Score()
{
    return (int)(( (decimal)TotalCorrect / TotalQuestions ) * 100);
}

现在我们将 1 转换为 1.0m,除以 2 得到 0.5m,再乘以 100 得到 50.0m。然后将其转换为 int 以获得 50。

注意:使用十进制而不是双精度。如果这样做,您就不太可能遇到奇怪的舍入错误。请记住,十进制准确地表示分母包含 2 和 5 的任意组合的分数;double 仅准确表示分母是 2 的幂的分数。

如果您希望允许非整数分数,后一种算法可能更好。

于 2013-03-18T19:44:31.440 回答
4

您将整数除以整数,因此结果是整数。由于结果为 0.5,因此作为整数即为 0。

只需先将任一操作数转换为double(或decimal):

( TotalCorrect / (double)TotalQuestions ) * 100;
于 2013-03-18T19:45:02.557 回答
2

您正在划分整数,结果被截断为零。将第一个转换为浮点或双精度。

public int Score()
{
    return (int)(((float)TotalCorrect / TotalQuestions ) * 100);
}
于 2013-03-18T19:44:37.487 回答