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

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

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

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    float a, b, d;
    char c;
    
    cin>>a>>b;
    cin>>c;
    
if(c=='+') cout<<a+b;
if(c=='-') cout<<a-b;
if(c=='*') cout<<a*b;
if(c=='/') cout<<setprecision(10)<<(float)a/b;
    return 0;
}

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

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    float a, b, d;
    char c;
    
    cin>>a>>b;
    cin>>c;
    
if(c=='+') cout<<a+b;
if(c=='-') cout<<a-b;
if(c=='*') cout<<a*b;
if(c=='/') cout<<setprecision(10)<<1.0*a/b; //here is the change
    return 0;
}

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

if(c=='/') cout<<setprecision(10)<<(float)a/b;
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

double a, b, d;

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

xzv2uavs

xzv2uavs3#

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

(float)a/b

a/b

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

1.0*a/b

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

#include <iostream>
#include <limits>

int main()
{
    std::cout << "std::numeric_limits<float>::digits10 = "
        << std::numeric_limits<float>::digits10
        << '\n';

    std::cout << "std::numeric_limits<double>::digits10 = "
        << std::numeric_limits<double>::digits10
        << '\n';
}

它的输出可能看起来像

std::numeric_limits<float>::digits10 = 6
std::numeric_limits<double>::digits10 = 15

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

( double )a/b

static_cast<double>( a )/b

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

double a, b;

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

相关问题