【问题标题】:C++ incorrect division & multiplication issueC++ 不正确的除法和乘法问题
【发布时间】:2023-02-24 23:03:08
【问题描述】:

我正在编写一个程序,我注意到我的 a 变量计算不正确。 这是代码:

int a = int(34 / 40 * 40);
std::cout << a << std::endl;

当我运行它时,它输出0。然而,34 / 40 * 40 是 34。

我想问题出在除法上,因为如果我用乘法 (34 / 40 = 0.85) 代替它,它就可以正常工作:

int a = int(0.85 * 40);
std::cout << a << std::endl;

输出: 34 在我的例子中,我可以只使用乘法,但是如果有人需要对变量进行除法怎么办?

【问题讨论】:

  • 当你除以整数时,结果是一个整数。你要int a = 34.0 / 40.0 * 40.0;
  • 34 / 40 * 40 在数学方面只有 34 而不是 C++(或许多其他编程语言)。在 C++ 中,34 / 40 为零,两个整数相除的结果总是另一个整数。

标签: c++


【解决方案1】:

如果用一个整数除以一个整数,结果总是一个整数。因此,当一个整数除以一个整数时,结果的提示被丢弃,在你的例子中 .85 被丢弃。

int = int / int

但是,如果分子或分母之一是浮点数,您的结果也将是浮点数。

float = float / float
float = int / float
float = float / int

在你的情况下:

float numerator = 34;
float denominator = 40;

int a = numerator / denominator * 40;

注意乘法组从左到右就像皮特贝克尔指出的那样

【讨论】:

  • 我会删除 int( ..) 转换,因为这里不需要它的代码味道。将结果分配给 a 足以获得 int
  • 小点:如果任何一个分子或者分母是一个浮点数(另一个是整数或浮点数)结果是一个浮点数。
  • 这遗漏了一个重点:从左到右的除法和乘法组。也就是说,numerator / denominator * 40 表示 (numerator / denominator) * 40 而不是 numerator / (denominator * 40)
  • @PeteBecker 好电话,我已经根据您的反馈编辑了答案。
【解决方案2】:

您的问题是整数算术一直用整数执行,除非您特别要求,否则任何操作数都不会更改为浮点格式。

因此 34 / 40 == 0 因为所有小数点都被去掉了,然后是普通的 0 * 40 == 0

另一方面,0.85 * 40具有doubleint类型的操作数,因此使用浮点运算,结果为34.0(类型double),然后转换为int @987654329 @.

请注意,单个浮点变量会导致结果为浮点数,因此 34.0 / 40 * 40 也可以。但请注意,这仅适用于在表达式分组中引入浮点数的点(然后变成对运算符优先级的讨论,请参阅底部的 (*))。

所以 (2 / 3) + (4.0 / 5) == 0.8 因为 (2 / 3) == 0 是使用整数算法计算的,然后是 (4.0 / 5) == 0.8 因为其中一个操作数是浮点数,最后是 0 + 0.8 == 0.8

如果您有疑问,请使用括号强制进行您想要的分组。在那张纸条上,34 * (40 / 40) 也可以工作——整数和浮点数。

(*) 如何计算表达式取决于operator precedence 和手动括号分组。因此,例如 34 / 40 * 40 分组为 (34 / 40) * 40,因为乘法和除法是从左到右的关联并且具有相同的优先级。

另一方面,2 / 3 + 4.0 / 5 分组为(2 / 3) + (4.0 / 5),因为乘法和除法的优先级高于加法。这也意味着 2 / 3 + 4.0 / 54.0 / 5 + 2 / 3 的计算结果相同,因为在这两种情况下,2/3 组在这两个组相加之前使用整数算法进行计算。

【讨论】:

  • “前进”并不能很好地描述事物的组合方式:34 / 40.0 * 40 也可以。这与评估顺序无关;是关于分组.除法和乘法组从左到右,所以 a / b * c(a / b) * c。评估顺序是关于以下情况发生的情况:f() / g() * h() 从左到右分组,就像前面的表达式一样,但三个函数调用的评估顺序未指定。
  • @PeteBecker 我在数学意义上使用了评估顺序,但我可以看出这可能会被误解评价顺序在编程中有不同的含义,所以我将其替换为分组根据你的建议。我还用一个注释替换了“onward”,该注释应该解释何时以更全面的方式进行整数到浮点数的提升。
【解决方案3】:
#include <iostream>

int main() {
    float a = 34.0 / 40.0;
    int b = a * 40;
    std::cout << a << std::endl;
    std::cout << b;
    return 0;
}

尝试这个

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    相关资源
    最近更新 更多