What is the difference in behavior between 1.0*a/b and (float)a/b when performing division in a simple calculator implementation?

huangapple go评论68阅读模式
英文:

What is the difference in behavior between 1.0*a/b and (float)a/b when performing division in a simple calculator implementation?

问题

The two lines in question are both related to the division operation in the code. They determine how the division result is displayed. Here's the difference between these two lines:

  1. cout << setprecision(10) << (float)a/b;

    In this line, the division result is first calculated as (float)a/b, which means it's performed as a floating-point division. Then, the setprecision(10) function is used to set the precision of the output to 10 decimal places. This ensures that the result will be displayed with a high level of decimal accuracy.

  2. cout << setprecision(10) << 1.0*a/b;

    In this line, the division result is calculated as 1.0*a/b. Here, 1.0 is used to explicitly convert one of the operands to a floating-point number. This ensures that the division operation is performed as floating-point division, similar to the first line. Then, like the first line, setprecision(10) is used to set the precision of the output to 10 decimal places.

The difference between these two lines is essentially how they handle type casting. In the first line, the type casting is done explicitly by (float)a, while in the second line, it's done by multiplying one of the operands (a) by 1.0. Both lines achieve the same result of performing floating-point division, and they set the precision for the output in the same way.

The reason for making this change in the code might be due to compiler or language differences in how division is handled, or it could be a matter of personal coding style. Regardless, both lines should produce the same output with high precision in most cases.

英文:

Here is the link to the problem
It's relatively easy looking problem with simple logic, of making your own calculator.
You input two numbers and character any of these four('+', '-', '*', '/') and output the answer.

So I wrote my code like this:

#include &lt;iostream&gt;
#include &lt;iomanip&gt;
using namespace std;

int main() {
	float a, b, d;
	char c;
	
	cin&gt;&gt;a&gt;&gt;b;
	cin&gt;&gt;c;
	
if(c==&#39;+&#39;) cout&lt;&lt;a+b;
if(c==&#39;-&#39;) cout&lt;&lt;a-b;
if(c==&#39;*&#39;) cout&lt;&lt;a*b;
if(c==&#39;/&#39;) cout&lt;&lt;setprecision(10)&lt;&lt;(float)a/b;
	return 0;
}

But it wasn't able to pass all the test cases. I tweaked a bit with code line of division and looked up other people's submission and found out correct answer as

#include &lt;iostream&gt;
#include &lt;iomanip&gt;
using namespace std;

int main() {
	float a, b, d;
	char c;
	
	cin&gt;&gt;a&gt;&gt;b;
	cin&gt;&gt;c;
	
if(c==&#39;+&#39;) cout&lt;&lt;a+b;
if(c==&#39;-&#39;) cout&lt;&lt;a-b;
if(c==&#39;*&#39;) cout&lt;&lt;a*b;
if(c==&#39;/&#39;) cout&lt;&lt;setprecision(10)&lt;&lt;1.0*a/b; //here is the change
	return 0;
}

so I wasn't able to understand what kind of input gives different output to above both codes

Difference between these two lines:

if(c==&#39;/&#39;) cout&lt;&lt;setprecision(10)&lt;&lt;(float)a/b;
if(c==&#39;/&#39;) cout&lt;&lt;setprecision(10)&lt;&lt;1.0*a/b;

答案1

得分: 3

主要区别在于1.0*a/b创建一个double(因为1.0double),而(float)a/b创建一个精度较低的float

此外,您可以使用std::numeric_limits&lt;T&gt;::digits10来了解在十进制基数下表示一个数字所需的位数,以避免损失。您会注意到对于floatdouble,情况如下:

  • std::numeric_limits&lt;float&gt;::digits10 == 6,这比您所需的精度(10)要低。
  • std::numeric_limits&lt;double&gt;::digits10 == 15,这比您所需的精度(10)要高。

有关精度的更多信息,请查阅cppreference

英文:

The main difference is that 1.0*a/b creates a double (as 1.0 is a double) while (float)a/b creates a float that has less precision.

Also you can use std::numeric_limits&lt;T&gt;::digits10 to know how many digits you need in base 10 to represent a number without loss. You'll notice that for float and double you have:

  • std::numeric_limits&lt;float&gt;::digits10 == 6 which is less than your required precision (10)
  • std::numeric_limits&lt;double&gt;::digits10 == 15 which is more than your required precision (10)

For more information about the precision you can check cppreference.

答案2

得分: 1

以下是翻译好的部分:

差异在于:

  • (float) a / ba 转换为 float,然后对 ab 进行除法运算。这实际上是不必要的,因为 ab 已经声明为 float,所以你可以直接写成 a / b
  • 1.0 * a / ba 乘以 1.0,而 1.0 是一个 double 字面值。这意味着在进行除法运算之前,ab 都将转换为双精度类型,除法的结果也将具有双精度精度。

后一种表达式也可以写成 (double) a / b。如果 double 是 IEEE-754 浮点数,那么与 1.0 的乘法是一个无操作,即什么都不做的操作。
1.0 相乘的唯一效果是,如果另一侧是 float,则它会被转换为 double

另一个解决方案是将所有变量声明为 double

double a, b, d;

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

英文:

The difference is that:

  • (float) a / b is converting a to float, and performing a division between a and b. This is actually unnecessary, because a and b are already declared as float, so you could have just as well written a / b
  • 1.0 * a / b is multiplying a with 1.0 and 1.0 is a double literal. This means that both a and b will be converted to double precision types before the division, and the result of the division will have double precision too.

The latter expression could have been written as (double) a / b as well. If double is an IEEE-754 floating-point number, then multiplication with 1.0 is a no-op, i.e. an operation that does nothing.
The only effect of multiplying with 1.0 is that the other side gets converted to double if it's a float.

Another solution is to declare all the variables as double:

double a, b, d;

If you need more precision, it's usually best to use the same level of precision everywhere, not just for one operation.

答案3

得分: 0

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

(float)a/b

a/b

是等价的,因为它们的类型都是float,这是由操作数的类型决定的。

这个表达式

1.0*a/b

由于常数1.0的类型为double,所以它的类型是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都没有被使用,可以删除。

英文:

In your original program these expressions

(float)a/b

and

a/b

are equivalent because the both expressions have the type float due to the type of the operands.

This expression

1.0*a/b

has the type double due to the constant 1.0 of the type double. So the result is more precised.

Try the following demonstration program.

#include &lt;iostream&gt;
#include &lt;limits&gt;

int main()
{
	std::cout &lt;&lt; &quot;std::numeric_limits&lt;float&gt;::digits10 = &quot;
		&lt;&lt; std::numeric_limits&lt;float&gt;::digits10
		&lt;&lt; &#39;\n&#39;;

	std::cout &lt;&lt; &quot;std::numeric_limits&lt;double&gt;::digits10 = &quot;
		&lt;&lt; std::numeric_limits&lt;double&gt;::digits10
		&lt;&lt; &#39;\n&#39;;
}

Its output might look like

std::numeric_limits&lt;float&gt;::digits10 = 6
std::numeric_limits&lt;double&gt;::digits10 = 15

As you can see objects of the type double can be represented more accurately with more digits.

You could write instead like

( double )a/b

or

static_cast&lt;double&gt;( a )/b

to get the same result. Or you could initially declare the variables as having the type double.

double a, b;

You need also to check whether the variable b is not equal to zero before performing the calculation.

Pay attention to that in the both programs the variable d is not used and may be removed.

huangapple
  • 本文由 发表于 2023年6月19日 21:26:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76507090.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定