相关疑难解决方法(0)

针对SSE2前处理器的Java运行时如何实现浮点基本操作?

在没有SSE2的情况下,针对没有SSE2的英特尔处理器的Java运行时strictfp是如何处理浮点非正规的?

即使将387 FPU设置为53位精度,它仍保持超大的指数范围:

  1. 强制检测每个中间结果的下溢/溢出,和
  2. 这使得很难避免非正规的双重舍入.

策略包括重新计算导致模拟浮点的非正规值的操作,或沿着这种技术的线路的永久指数偏移,为OCaml配备63位浮点数,从指数借用一点以避免双重-四舍五入.

在任何情况下,除非可以静态地确定操作不下溢/溢出,否则我认为没有办法避免每个浮点计算至少有一个条件分支.如何处理异常(溢出/下溢)情况是我的问题的一部分,但这不能与表示的问题分开(永久指数偏移策略似乎意味着只需要检查溢出).

java floating-point

12
推荐指数
1
解决办法
1147
查看次数

是`x!= x`是一种可以测试NaN的便携方法吗?

在C中你可以测试是否使用NaN加倍isnan(x).然而,许多在线地方,包括例如这个SO答案,说你可以简单地使用x!=x.

x!=x在任何C说明书中这是保证测试,如果x为NaN的方法?我自己找不到它,我希望我的代码能够与不同的编译器一起工作.

c floating-point nan

12
推荐指数
2
解决办法
784
查看次数

相同的FLT_EVAL_METHOD,GCC/Clang中的结果不同

当使用GCC(4.8.2)和Clang(3.5.1)编译时,以下程序(从此处改编)给出不一致的结果.特别是,GCC结果即使在何时FLT_EVAL_METHOD也不会改变.

#include <stdio.h>
#include <float.h>

int r1;
double ten = 10.0;

int main(int c, char **v) {
  printf("FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
  r1 = 0.1 == (1.0 / ten);
  printf("0.1 = %a, 1.0/ten = %a\n", 0.1, 1.0 / ten);
  printf("r1=%d\n", r1);
}
Run Code Online (Sandbox Code Playgroud)

测试:

$ gcc -std=c99 t.c && ./a.out
FLT_EVAL_METHOD = 0
0.1 = 0x1.999999999999ap-4, 1.0/ten = 0x1.999999999999ap-4
r1=1

$ gcc -std=c99 -mpfmath=387 t.c && ./a.out
FLT_EVAL_METHOD = 2
0.1 = 0x0.0000000000001p-1022, 1.0/ten = 0x0p+0
r1=1

$ …
Run Code Online (Sandbox Code Playgroud)

c floating-point gcc clang

7
推荐指数
1
解决办法
544
查看次数

显然具有不同输出的相同数学表达式

以下代码将在x86 32位计算机上为变量"e"和"f"输出不同的结果,但在x86 64位计算机上会产生相同的结果.为什么?从理论上讲,正在评估相同的表达,但从技术上讲,它不是.

#include <cstdio>
main()
{
  double a,b,c,d,e,f;
  a=-8988465674311578540726.0;
  b=+8988465674311578540726.0;
  c=1925283223.0;
  d=4294967296.0;
  e=(c/d)*(b-a)+a;
  printf("%.80f\n",e);
  f=c/d;
  f*=(b-a);
  f+=a;
  printf("%.80f\n",f);
}
Run Code Online (Sandbox Code Playgroud)

注意...使用'gcc -m32'可以生成32位x86代码,谢谢@Peter Cordes /sf/users/15689271/

也可以看看

boost :: random :: uniform_real_distribution应该是跨处理器的相同吗?

---为用户Madivad更新

64 bit output 
-930037765265417043968.00000...
-930037765265417043968.00000...

32 bit output
-930037765265416519680.00000...
-930037765265417043968.00000...
Run Code Online (Sandbox Code Playgroud)

这个python代码可以给出"数学上正确"的输出

from fractions import Fraction
a=-8988465674311578540726
b=8988465674311578540726
c=1925283223
d=4294967296
print "%.80f" % float(Fraction(c,d)*(b-a)+a)

-930037765265416519680.000...
Run Code Online (Sandbox Code Playgroud)

c++ floating-point precision

6
推荐指数
1
解决办法
150
查看次数

用于增强中间浮点计算精度的编译器标志

gcc/clang中是否有一个标志指定中间浮点计算的精度?

假设我有一个C代码

double x = 3.1415926;
double y = 1.414;
double z = x * y;
Run Code Online (Sandbox Code Playgroud)

是否有编译器标志允许以用户机器的最高精度计算'x*y',例如,long-double(64位尾数),然后截断为double(53位尾数,声明变量类型的精度)?

仅供参考,我在64位计算机上使用Ubuntu 14.04.

c c++ floating-point precision compilation

5
推荐指数
1
解决办法
1008
查看次数

"双重"操作和C语言优化

我最近分析了一个用VS2005编译的旧代码,因为"debug"(无优化)和"release"(/ O2/Oi/Ot选项)编译中的数字行为不同.(简化)代码如下所示:

void f(double x1, double y1, double x2, double y2)
{
double a1, a2, d;

a1 = atan2(y1,x1);
a2 = atan2(y2,x2);
d = a1 - a2;
if (d == 0.0) { // NOTE: I know that == on reals is "evil"!
   printf("EQUAL!\n");
}
Run Code Online (Sandbox Code Playgroud)

f如果使用相同的值对(例如f(1,2,1,2))调用,则该函数应打印"EQUAL" ,但这并不总是发生在"release"中.实际上,编译器已经优化了代码,好像它是完全相同的d = a1-atan2(y2,x2)并且完全删除了对中间变量的赋值a2.此外,它利用了第二个atan2()结果已经在FPU堆栈上的事实,因此a1在FPU上重新加载并减去这些值.问题是FPU以扩展精度(80位)工作,而a1"仅"加倍(64位),因此将第一个atan2()结果保存在内存中实际上已经失去了精度.最终,d包含扩展精度和双精度之间的"转换错误".

我完全知道==应该避免使用float/double的身份(操作符).我的问题不是关于如何检查双打之间的接近程度.我的问题是如何考虑"契约"对局部变量的赋值.按照我的"天真"观点,赋值应强制编译器将值转换为变量类型表示的精度(在我的例子中为double).如果变量是"浮动"怎么办?如果他们是"int"(很奇怪,但合法)怎么办?

那么,简而言之,C标准对这些案例有何评价?

c c++ floating-point visual-studio

4
推荐指数
1
解决办法
507
查看次数

标签 统计

floating-point ×6

c ×4

c++ ×3

precision ×2

clang ×1

compilation ×1

gcc ×1

java ×1

nan ×1

visual-studio ×1