【发布时间】:2011-07-25 23:29:16
【问题描述】:
小浮点数 - 接近 0 - 和大浮点数 - 远离 0 的计算有什么区别吗?
【问题讨论】:
标签: c++ c types floating-point
小浮点数 - 接近 0 - 和大浮点数 - 远离 0 的计算有什么区别吗?
【问题讨论】:
标签: c++ c types floating-point
据我了解处理器的工作原理,应该完全没有区别
【讨论】:
这完全取决于用于计算浮点数的平台。一般来说,应该有很小的差异或没有差异。在内部,浮点数使用归一化尾数(介于 0.5 和 1.0 之间的值)、符号和指数来表示。小数和大数的区别在于指数的值。
话虽如此,但有一个明显的例外。非常小的浮点数,即所谓的次正规数或非规格化数的表示方式不同,一些 FPU:s 不支持它们。在这种情况下,他们会逃到软件来执行计算,这真的很慢。具体来说,这是音频软件中的一个问题,声音可以响起到听不见的东西,但是一旦足够小,就会使计算速度显着变慢。
【讨论】:
不,根本没有区别(忽略精度问题)。浮点数始终使用符号、分数和指数来表示数字。根据其“大小”并没有任何区别,并且在小数字或整数的情况下使用某种整数替换没有任何意义(只会导致额外的开销) - 计算你必须转换它们反正又来了。
【讨论】:
这取决于您在谈论哪种计算。无论数字的大小如何,将两个数字加在一起可能需要相同的时间长度。在除法的情况下,操作数的大小会有所不同——例如,参见Intel reference manual 第 C.34 页:
如果您尝试编译以下代码,您可以看到它的实际效果:
// Compile with -O0 to avoid optimising out loop!
#include <iostream>
#include <sys/time.h>
#include <limits>
void test(float a, float b)
{
struct timeval start, end;
gettimeofday(&start, NULL);
for (size_t i=0; i<500000; ++i)
{
float result = a/b;
}
gettimeofday(&end, NULL);
long seconds, useconds;
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
double ms = ((seconds) * 1000 + useconds/1000.0);
std::cout << a << "/" << b << " takes " << ms << "ms" << std::endl;
}
int main()
{
test(1,2);
test(0.0005,1.0e+35);
}
为我提供以下输出
1/2 需要 1.032 毫秒
0.0005/1e+35 耗时 32.287 毫秒
【讨论】:
1/b,乘以 500.000 次)
我相信这些数字可以放在相同的数据类型中时没有区别。
【讨论】: