【问题标题】:Floats and Longs浮点数和多头
【发布时间】:2012-03-02 02:56:11
【问题描述】:

我使用 sizeof 检查我的64 bit amd opteron 机器中的 long 和 float 的大小。两者都显示为 4。

当我检查 limits.hfloat.h 的最大浮点和长值时,我得到了这些值:

Max value of Float:340282346638528859811704183484516925440.000000

Max value of long:9223372036854775807

既然它们的大小相同,那么与 long 相比,float 怎么能存储这么大的值呢?

我假设它们对浮点数有不同的存储表示。如果是这样,这是否会影响性能:即,使用 long 是否比使用 float 更快?

【问题讨论】:

  • 有些不对劲。如果sizeof(long) == 4,那么long的最大值只能是2147483647
  • 只有 32 位的 long 值是错误的。应该只有 20 亿左右。
  • 一些 64 位 ABI 有 32 位长和 64 位长 - 其他的都使用 64 位。
  • 这些最大值分别从 float.h 和 limits.h 打印出来。现在我研究了一下,它不应该那么大是有道理的
  • 如果 sizeof(long) = 4,那么最长的最大值确实是 2147483647 并且您误解了 limits.h 的内容,可能将 long long 的最大值误认为 long 的最大值。

标签: c memory


【解决方案1】:

这是一个权衡。

一个32位有符号整数可以表示-231和+231-1之间的每一个整数。

32 位浮点数使用指数表示法,可以表达范围更广的数字,但无法表达该范围内的所有数字——甚至不能表达所有整数。它使用一些位来表示分数,其余位表示指数。它实际上是 6.023*1023 之类的符号的二进制等价物,或者你有什么,在范围末端可表示的数字之间的距离非常大。

要了解更多信息,我会阅读 David Goldberg 撰写的这篇文章,“每个计算机科学家应该了解的浮点运算知识”:http://web.cse.msu.edu/~cse320/Documents/FloatingPoint.pdf

顺便说一句,在您的平台上,我希望 float 是 32 位的数量,而 long 是 64 位的数量,但这与整体观点并不密切。

性能在这里很难定义。浮点运算可能会或可能不会比整数运算花费更长的时间,具体取决于运算的性质以及是否对它们使用硬件加速。通常,像加法和减法这样的运算在整数中要快得多——乘法和除法则要慢得多。在某一时刻,人们在进行计算时试图将每个周期都搞砸,他们会将实数表示为“定点”算术并使用整数来表示它们,但这种技巧现在已经很少见了。 (在您使用的 Opteron 上,浮点运算确实是硬件加速的。)

几乎所有运行 C 的平台都有不同的“浮点”和“双”表示,“双”浮点是双精度的,即占据两倍多位的表示。除了空间权衡之外,这些操作通常会比较慢,而且如果他们的计算精度不要求加倍,那么高度关注性能的人会尝试使用浮点数。

【讨论】:

    【解决方案2】:

    long 上的操作是否比 float 上的操作快并不重要,反之亦然。

    如果您只需要表示整数值,请使用整数类型。您应该使用哪种类型取决于您使用它的用途(有符号与无符号,shortintlonglong long,或@987654327 中的精确宽度类型之一@)。

    如果您需要表示实数,请使用以下浮点类型之一:floatdoublelong double。 (float 实际上用得不多,除非内存空间非常宝贵;double 的精度更高,而且通常不比float 慢。)

    简而言之,选择一种语义符合您需要的类型,然后再担心性能。快速得到错误答案并没有什么好处。

    至于存储表示,其他答案几乎涵盖了这一点。通常无符号整数使用它们的所有位来表示值,有符号整数使用一位来表示符号(尽管通常不是直接的),而浮点类型将一位用于符号,几位用于指数,其余的为价值。 (这太简单化了。)

    【讨论】:

      【解决方案3】:

      浮点数学本身就是一门学科,但是是的:int 类型通常比 float 类型快。

      要记住的一个技巧是,并非所有值都可以表示为浮点数。 例如最接近 1.9 的可能是 1.899999999。这会导致一些有趣的错误,您会说如果 (v == 1.9) 事情发生意外!

      【讨论】:

      • 我使用的情况是,我只使用整数(不是十进制数)。我需要表示比整数长的数字。这么长是理想的方式。但是由于某种原因,当我使用 long 时,我使用的库会崩溃。但是当它使用浮点数时它可以正常工作。所以我试图用花车代替长。浮点数是否会丢失整数的存储?
      • 任何给定的 API 调用都只会使用一种类型的数字。如果你想知道为什么当你输入错误类型的数据时它会崩溃,我建议你可能还不了解 C 类型系统的工作方式——花一些时间阅读它可能是值得的,因为这是不是唯一一个你会遇到麻烦的地方。
      • @TheFlyingDutchman:术语很重要。不需要表示长于整数的数字(没有这样的数字),需要表示长于ints 的数字。 int 是几种整数类型之一。 long 是另一个。
      【解决方案4】:

      如果是这样,这是否会影响性能:即,使用 long 是否比使用 float 快?

      是的,longs 的算术运算将比 floats 更快。

      我假设它们对浮点数有不同的存储表示。

      是的。 float 类型采用 IEEE 754(单精度)格式。

      既然它们的大小相同,那么与 long 相比,float 怎么能存储这么大的值呢?

      它已针对在几个点(例如接近 0)存储数字进行了优化,但并未针对准确度进行优化。例如,您可以将 1 加到 1000000000。使用 float,总和可能不会有任何差异(1000000000 而不是 1000000001),但使用 long 会有差异。

      【讨论】:

      • long 算术比float 算术更快不是必要。一些系统针对浮点进行了大量优化。
      • @Keith Thompson,没错,但我猜 OP 所说的 AMD Opteron 不是其中之一。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多