【发布时间】:2017-03-27 21:47:54
【问题描述】:
我需要执行 400 * 256.3 的简单乘法运算。结果是 102520。简单明了。但是在 C++(或 C)中实现这种乘法对我来说有点棘手和困惑。
我知道浮点数不像在计算机中那样表示。我写了代码来说明这种情况。输出也附上。
所以,如果我使用浮点类型变量进行乘法运算,我会遇到舍入误差。使用双类型变量可以避免这个问题。但是假设我在嵌入式系统上的资源非常有限,我必须尽可能地优化变量类型,如何使用浮点类型变量执行乘法而不容易出现舍入错误?
我知道计算机完成的浮点数学运算根本没有被破坏。但我很好奇执行浮点数学的最佳实践。 256.3 只是一个说明值。我不知道在运行时我会得到什么浮点值。但它肯定是一个浮点值。
int main()
{
//perform 400 * 256.3
//result should be 102520
float floatResult = 0.00f;
int intResult = 0;
double doubleResult = 0.00;
//float = int * float
floatResult = 400 * 256.3f;
printf("400 * 256.3f = (float)->%f\n", floatResult);
//float = float * float
floatResult = 400.00f * 256.3f;
printf("400.00f * 256.3f = (float)->%f\n", floatResult);
printf("\n");
//int = int * float
intResult = 400 * 256.3f;
printf("400 * 256.3f = (int)->%d\n", intResult);
//int = float * float;
intResult = 400.00f * 256.3f;
printf("400.00f * 256.3f = (int)->%d\n", intResult);
printf("\n");
//double = double * double
doubleResult = 400.00 * 256.3;
printf("400.00 * 256.3 = (double)->%f\n", doubleResult);
//int = double * double;
intResult = 400.00 * 256.3;
printf("400.00 * 256.3 = (int)->%d\n", intResult);
printf("\n");
//double = int * double
doubleResult = 400 * 256.3;
printf("400 * 256.3 = (double)->%f\n", doubleResult);
//int = int * double
intResult = 400 * 256.3;
printf("400 * 256.3 = (int)->%d\n", intResult);
printf("\n");
//will double give me rounding error?
if (((400.00 * 256.3) - 102520) != 0) {
printf("Double give me rounding error!\n");
}
//will float give me rounding error?
if (((400.00f * 256.3f) - 102520) != 0) {
printf("Float give me rounding error!\n");
}
return 0;
}
【问题讨论】:
-
答案很简单:你不能。舍入问题是“内置”在使用 IEEE 浮点格式的计算机上,这几乎是所有问题。
-
值 256.3f 也在骗你,你无法避免。
-
您可以使用其他数据类型,例如固定精度类型或有理/分数库。
-
@Olaf 我的意思是说 C++ 或 C。斜线是“或”的符号。我知道计算机中的浮点实现,并且我知道它没有损坏。我只是好奇是否有办法让我使用浮点变量类型并且不会暴露于舍入错误。
标签: c precision multiplication floating-accuracy