为什么微软放弃了长双数据类型?

inf*_*inf 21 c++ floating-point long-double visual-studio

不久前我写了一个程序,它使用了一些阶乘函数.我使用long double数据类型来支持"相对"大数字.

现在,我从代码块改为Visualstudio 2010,我想知道为什么我的程序不再工作,直到我在一些研究中意识到MS已经放弃了长双数据类型.这有什么特别的原因吗?对我而言,它看起来非常像技术方面的倒退.

有没有其他选择?(我也很乐意使用boost库中的替代品).

Lig*_*ica 14

我不确定为什么你认为它long double被"放弃",因为它是C++标准的一部分,因此一个兼容的实现必须实现它.

他们所做的 "放弃"是long double数学函数的重载,他们这样做是因为:

但是,在Win32编程中,long double数据类型映射到double64位精度数据类型.

反过来,随着long double旧版VS版本的80位,这是因为:

FP代码生成已经转向使用SSE/SSE2/SSE3指令集而不是x87 FP堆栈,因为这是AMD和英特尔近期和未来的芯片代表都在关注其性能工作.这些指令集仅支持32和64位FP格式.

尽管如此,他们选择不支持这些重载,即使是相同大小doublelong double类型(两者都可能是64位),也是一种耻辱,因为它们也是 C++标准的一部分.但是,那就是微软为你而存在的.专心固执.

[n3290: 26.8]:除了double数学函数的版本之外<cmath>,C++还添加floatlong double重载了这些函数的版本,具有相同的语义.

然而,尽管这些重载在Visual Studio中基本上是过时了,他们仍然可用,所以你应该仍然能够使用它们:

Microsoft运行时库仅提供long double数学函数的版本以实现向后兼容.


有没有其他选择?(我也很乐意使用boost库中的替代品).

听起来像你一直依赖于long double支持特定范围的数值,并且当在不同的工具链中发生变化时,它会遇到回归问题.

如果您有特定的数值范围要求,请使用固定范围积分类型.在这里你有几个选择:

  • stdint.h - 一些C99工具链作为扩展支持的C99功能;
  • stdint.h - Boost重新实现为库的C99功能;
  • cstdint - 如果您正在编写C++ 0x代码,则可能会使用C++ 0x功能.

  • 你不能只丢掉'long double`.这是标准的明确部分.他们所做的是有效地放弃对'long double`重载的支持,他们这样做是因为他们碰巧决定将`long double`映射到`double`(_this_是有意义的一点).对他们来说不幸的是,重载也是语言的一个明确部分,所以他们真的玩火. (5认同)
  • *“这是如何“支持”那些标准重载的?”* - 它们就在那里。它们不应该用于*“新代码”*。然而,没有提到 Visual Studio 将放弃这些兼容实现,也没有提到 VS 不会构建旧代码。调用“long double”重载甚至不会触发弃用警告。VS 在这方面完全符合标准,即使您一直暗示情况并非如此,或者可能不再如此。这一切都没有道理,而且这一切在 5 年内都没有实现。 (4认同)
  • 为什么不?x87 FPU支持80位浮点.他们可以将`long double`定义为80位浮点数. (3认同)
  • @ybungalobill:除了x86系统不允许你保持这种方式.如果它们使x87为80位表示,你只能在寄存器中存储`long double`. (3认同)
  • @DeadMG嗯?请参阅带有操作码DB/5的英特尔指令集手册FLD变体. (2认同)
  • @Joachim:事实并非如此.即使是microsoft编译器也默认使用FPU.其他编译器(GCC,Intel?)支持80位长的双精度数.此外,当使用long double时,您可以实现一个使用SSE进行双精度和浮点数以及回退到FPU的编译器. (2认同)
  • 微软在Win32中删除了x87`long double`,这是有道理的:Win32是Windows NT引入的API,也是在MIPS和Alpha上运行的.当然英特尔编译器可以支持x87双打; 非英特尔拱门的可移植性对他们来说是一种反感. (2认同)