float类型的计算成本

3

在计算机科学中,接近0的小浮点数和远离0的大浮点数之间有什么区别吗?

5个回答

4
据我了解处理器的工作原理,应该完全没有任何区别。

4
这完全取决于计算浮点数所使用的平台。一般来说,应该几乎没有什么区别。在内部,浮点数使用规范化的尾数(介于0.5和1.0之间的值)、符号和指数来表示。小数和大数之间的区别在于指数的值。
话虽如此,有一个明显的例外。真正小的浮点数,也就是所谓的“次正常数”或“非规格化数”,它们的表示方法不同,有些FPU不支持它们。在这种情况下,它们会逃到软件中进行计算,这样会非常慢。具体来说,这在音频软件中是一个问题,因为声音可能会衰减到听不到的程度,但一旦它足够小,它会使计算显著变慢。

1

不,完全没有区别(忽略精度问题)。浮点数总是使用符号、分数和指数来表示数字。它的“大小”不会有任何差异,并且在小数或整数的情况下使用某种整数替换也没有意义(只会增加额外的开销)- 无论如何,为了计算,您仍然需要将它们转换回去。


0

这取决于你所谈论的计算类型。将两个数字相加可能需要相同的时间长度,无论数字的大小如何。在除法的情况下,操作数的大小可能会有所不同-例如,请参见Intel参考手册第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 毫秒


你需要确保在这些测试中关闭优化器,因为在某些情况下它们可能会完全优化掉代码。 - Chad
是的,这很重要!我在代码中已经放了一个注释来表明这一点,但再次强调是值得的… - Matt
优化器不仅可以删除该行,而且较不激进的优化器也可以将其转换为乘法(计算1/b一次,然后乘以500,000次)。 - MSalters
将某物除以二通常是一项快速操作。有趣的问题是,是否“小”/2和“大”/2一样快。 - Lindydancer
我在这里使用的两个示例除法是相当任意的 - 如果您测试大范围的分子和分母的除法,您会发现大多数除法运行速度大约相同。将巨大的数字除以微小的数字,或将微小的数字除以巨大的数字将会更慢。对于整数除法来说,情况就不同了,速度取决于结果的大小。 - Matt

0

我相信当这些数字可以放在同一数据类型中时,它们之间没有区别。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接