c++ 在一个简单的计算器实现中执行除法时,1.0*a/b和(float)a/b之间的行为有什么区别?

5w9g7ksd  于 2023-06-25  发布在  其他
关注(0)|答案(3)|浏览(464)

Here是问题的链接这是相对容易看的问题与简单的逻辑,使自己的计算器。输入两个数字,并将这四个数字('+','-','*','/')中的任何一个字符化,然后输出答案。
所以我把代码写成这样:

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. int main() {
  5. float a, b, d;
  6. char c;
  7. cin>>a>>b;
  8. cin>>c;
  9. if(c=='+') cout<<a+b;
  10. if(c=='-') cout<<a-b;
  11. if(c=='*') cout<<a*b;
  12. if(c=='/') cout<<setprecision(10)<<(float)a/b;
  13. return 0;
  14. }

但它没能通过所有测试用例。我调整了一下代码行的划分和查找其他人的提交,并找到正确的答案作为

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. int main() {
  5. float a, b, d;
  6. char c;
  7. cin>>a>>b;
  8. cin>>c;
  9. if(c=='+') cout<<a+b;
  10. if(c=='-') cout<<a-b;
  11. if(c=='*') cout<<a*b;
  12. if(c=='/') cout<<setprecision(10)<<1.0*a/b; //here is the change
  13. return 0;
  14. }

所以我不能理解什么样的输入会给上面的两个代码带来不同的输出
这两条线的区别:

  1. if(c=='/') cout<<setprecision(10)<<(float)a/b;
  2. if(c=='/') cout<<setprecision(10)<<1.0*a/b;
nkoocmlb

nkoocmlb1#

主要区别是1.0*a/b创建一个double(因为1.0是double),而(float)a/b创建一个精度较低的float
你也可以使用std::numeric_limits<T>::digits10来知道你需要多少个十进制的数字来表示一个数字而不会丢失。您会注意到,对于floatdouble,您有:

  • std::numeric_limits<float>::digits10 == 6小于您要求的精度(10)
  • std::numeric_limits<double>::digits10 == 15,超过您所需的精度(10)

有关精度的更多信息,您可以检查cppreference

c90pui9n

c90pui9n2#

区别在于:

  • (float) a / ba转换为float,并在ab之间执行除法。这实际上是不必要的,因为ab已经被声明为float,所以您也可以编写为a / b
  • 1.0 * a / b是将a乘以1.0,而1.0double文字。这意味着ab都将在除法之前转换为双精度类型,除法的结果也将具有双精度。

后一个表达式也可以写成(double) a / b。如果double是IEEE-754浮点数,则与1.0相乘是无操作,即一个什么都不做的手术与1.0相乘的唯一效果是,如果另一边是float,则转换为double
另一种解决方案是将所有变量声明为double

  1. double a, b, d;

如果您需要更高的精度,通常最好在任何地方使用相同级别的精度,而不仅仅是一次操作。

xzv2uavs

xzv2uavs3#

在你的原始程序中这些表达式

  1. (float)a/b

  1. a/b

是等效的,因为两个表达式的类型都是float,这是由于操作数的类型。
这个表情

  1. 1.0*a/b

由于double类型的常数1.0,因此具有double类型。因此,结果更加精确。
尝试以下演示程序。

  1. #include <iostream>
  2. #include <limits>
  3. int main()
  4. {
  5. std::cout << "std::numeric_limits<float>::digits10 = "
  6. << std::numeric_limits<float>::digits10
  7. << '\n';
  8. std::cout << "std::numeric_limits<double>::digits10 = "
  9. << std::numeric_limits<double>::digits10
  10. << '\n';
  11. }

它的输出可能看起来像

  1. std::numeric_limits<float>::digits10 = 6
  2. std::numeric_limits<double>::digits10 = 15

正如您所看到的,double类型的对象可以用更多的数字更准确地表示。
你可以这样写

  1. ( double )a/b

  1. static_cast<double>( a )/b

得到同样的结果。或者,您可以在一开始将变量声明为double类型。

  1. double a, b;

您还需要在执行计算之前检查变量b是否不等于零。
请注意,在这两个程序中,变量d没有使用,可能会被删除。

展开查看全部

相关问题