我有一个函数,它接受两个字符串(浮点数),操作和浮点数的位宽:
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:
答案 0 :(得分:2)
C ++没有指定float
或double
使用哪种格式。如果使用IEEE-754 binary32和binary64,则+
,-
,*
,/
或sqrt
不会发生双取整错误。在给定float x
和float 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