使用双精度浮点运算

时间:2020-06-05 06:22:51

标签: c++ casting floating-point

我有一个函数,它接受两个字符串(浮点数),操作和浮点数的位宽:

EvaluateFloat(const string &str1, const string &str2, enum operation/*add,subtract, multiply,div*/, unsigned int bit-width, string &output)

输入str1和str2可以是float(32位)或double(64位)。

可以吗?如果将输入存储为double并执行double操作,而与位宽无关,并且取决于位宽类型转换,则将其浮置为32位。 例如

double num1 = atof(str1);
double num2 = atof(str2);
double result = num1 operation num2; //! operation will resolved using switch
if(32 == bit-width)
{
 float f_result = result;
 output = std::to_string(f_result);
}
else
{
 output = std::to_string(result);
}

如果我使用浮点类型对浮点运算执行了操作,我可以安全地假设f_result完全相同。

float f_num1 = num1;
float f_num2 = num2;
float f_result = f_num1 operation f_num2

PS:

  1. 我们假设不会有任何级联操作,即out = a + b + c 相反,它将转换为:temp = a + b out = temp + c
  2. 我不关心inf和nan值。
  3. 我正在尝试编码冗余,否则我将执行两个相同的操作 两次,一次为浮动,另一次为两次

2 个答案:

答案 0 :(得分:2)

C ++没有指定floatdouble使用哪种格式。如果使用IEEE-754 binary32和binary64,则+-*/sqrt不会发生双取整错误。在给定float xfloat y的情况下,保持以下条件(左侧为float,右侧为double

  • x+y = (float) ((double) x + (double) y)
  • x-y = (float) ((double) x - (double) y)
  • x*y = (float) ((double) x * (double) y)
  • x/y = (float) ((double) x / (double) y)
  • sqrt(x) = (float) sqrt((double) x)

这是塞缪尔·A·菲格罗亚·德尔·西德(Samuel A. Figueroa del Cid)于2000年1月在纽约大学发表的论文A Rigorous Framework for Fully Supporting the IEEE Standard for Floating-Point Arithmetic in High-Level Programming Languages。本质上,double超出float的位数(位)太多,以至于double的舍入永远不会掩盖正确获得这些操作结果的float所需的信息。 (这一般无法满足操作要求;它取决于这些操作的属性。)在第57页上,Figueroa del Cid给出了一个表格,该表格显示,如果float格式具有 p 位,然后,为避免双舍入错误,double必须具有2 p +1位用于加法或减法,2 p 位用于乘法和除法,以及2 sqrt的p +2。由于binary32的有效位数为24位,而double的有效位数为53,因此可以满足这些要求。 (有关详细信息,请参见本文。有一些警告,例如 p 对于各种操作必须至少为2或4。)

答案 1 :(得分:1)

根据标准double上的浮点运算等效于以无限精度进行运算。如果将其转换为float,我们现在将其舍入两次。通常,这不等同于首先舍入到float。例如。 0.47四舍五入为0.5,四舍五入为1,但0.47四舍五入直接为0。正如chtz所提到的,两个浮点数的乘积应始终完全是两倍(使用IEEE数学,double的精度是{{ 1}}),因此当我们强制转换为float时,我们仍然只损失一次精度,因此结果应该是相同的。同样,加减法也不成问题。

除法不能精确地表示为两倍(甚至是1/3),因此我们可能认为除法存在问题。但是,我在夜间运行了示例代码,尝试了3万亿多个案例,但没有发现将原始除法作为float给出不同答案的情况。

double