当允许使用的唯一浮点指令是387个时,几乎不可能(*)以合理的成本提供严格的IEEE 754语义.当希望保持FPU在完整的64位有效数字上工作时,这一点特别困难,因此该long double类型可用于扩展精度.通常的"解决方案"是以唯一可用的精度进行中间计算,并在或多或少明确定义的场合转换为较低的精度.
根据Joseph S. Myers在2008年GCC邮件列表中发布的解释,GCC的最新版本处理中间计算中的过多精度.gcc -std=c99 -mno-sse2 -mfpmath=387据我所知,这个描述使程序编译完全可预测,到最后一点.如果它偶然没有,那就是一个错误而且它将被修复:约瑟夫S.迈尔斯在他的帖子中声明的意图是使其可预测.
是否记录了Clang如何处理超额精度(比如何时使用该选项-mno-sse2),以及在哪里?
(*)编辑:这是夸大其词.当允许将x87 FPU配置为使用53位有效数字时,这有点令人讨厌,但并不难以模拟binary64.
在下面的R ..评论之后,这里是我与Clang的最新版本之间的短暂互动的日志:
Hexa:~ $ clang -v
Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
Hexa:~ $ cat fem.c
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <fenv.h>
double x;
double y = 2.0;
double z = 1.0;
int main(){
x = y + z;
printf("%d\n", (int) FLT_EVAL_METHOD);
}
Hexa:~ $ clang …Run Code Online (Sandbox Code Playgroud) 具体来说,我谈论的是x87 PC架构和C编译器。
我正在编写自己的解释器,double数据类型背后的推理使我感到困惑。特别是在效率方面。有人可以解释为什么C选择了64位double而不是硬件本机80位double吗?又为什么硬件没有设置在80位double上呢?每种性能都有什么影响?我想使用80位double作为默认数字类型。但是编译器开发人员的选择让我担心这不是最佳选择。
double在x86上仅短2个字节,为什么编译器long double默认不使用10个字节?long doublevs所带来的额外精度的例子double吗?long double 默认情况下禁用它?long double典型的x86 / x64 PC硬件的差/慢多少?以下代码在x86 32位与64位处理器上产生不同的输出.
应该这样吗?如果我用std :: uniform_real_distribution替换它并使用-std = c ++ 11编译它会在两个处理器上产生相同的输出.
#include <iostream>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
int main()
{
boost::mt19937 gen;
gen.seed(4294653137UL);
std::cout.precision(1000);
double lo = - std::numeric_limits<double>::max() / 2 ;
double hi = + std::numeric_limits<double>::max() / 2 ;
boost::random::uniform_real_distribution<double> boost_distrib(lo, hi);
std::cout << "lo " << lo << '\n';
std::cout << "hi " << hi << "\n\n";
std::cout << "boost distrib gen " << boost_distrib(gen) << '\n';
}
Run Code Online (Sandbox Code Playgroud) int y = 89;
int foo = (y / 10.0 - y / 10) * 10;
int bar = (89 / 10.0 - 89 / 10) * 10;
cout << foo << ' ' << bar << '\n';
Run Code Online (Sandbox Code Playgroud)
上面的代码是想得到一个整数y的最后一位,奇怪的是foo is8和bar is 9,为什么会这样呢?两个版本的表达式有什么区别?
c++ ×2
x86 ×2
boost ×1
c ×1
c99 ×1
clang ×1
long-double ×1
performance ×1
random ×1
visual-c++ ×1