标签: ieee-754

哪种语言能让IEEE 754正确?

我只是花了一周的时间来讨论这个主题,并没有发现任何符合IEEE 754规范的语言.

即使GCC也不尊重相关的C99部分(它忽略了FENV_ACCESS的编译指示,而且我被告知比我的工作示例纯粹是运气).

使用库函数尊重规范是不可能的(AFAIK),您需要语言支持,因为当您使用标志或舍入时,禁止一些常见的优化.

所以这是我真正的问题:那里有语言(来自C/C++或原始程序集的appart)可以访问舍入模式,异常标志和微积分吗?

ieee-754

11
推荐指数
1
解决办法
1332
查看次数

如何在Perl中将四个字符转换为32位IEEE-754浮点数?

我有一个项目,其中一个函数接收四个8位字符,并需要将生成的32位IEEE-754浮点数转换为常规Perl数.似乎应该有比下面的工作代码更快的方式,但我还没有找到一个更简单的包函数.

它不起作用,但它似乎很接近:

$float = unpack("f", pack("C4", @array[0..3]);  # Fails for small numbers
Run Code Online (Sandbox Code Playgroud)

作品:

@bits0 = split('', unpack("B8", pack("C", shift)));
@bits1 = split('', unpack("B8", pack("C", shift)));
@bits2 = split('', unpack("B8", pack("C", shift)));
@bits3 = split('', unpack("B8", pack("C", shift)));
push @bits, @bits3, @bits2, @bits1, @bits0;

$mantbit = shift(@bits);
$mantsign = $mantbit ? -1 : 1;
$exp = ord(pack("B8", join("",@bits[0..7])));
splice(@bits, 0, 8);

# Convert fractional float to decimal
for (my $i = 0; $i < 23; $i++) {
    $f = $bits[$i] * …
Run Code Online (Sandbox Code Playgroud)

floating-point perl ieee-754

11
推荐指数
2
解决办法
6012
查看次数

iOS ARM设备(iPhone 4)支持低于标准的IEEE 754浮点数

在将应用程序从Linux x86移植到iOS ARM(iPhone 4)时,我发现浮点算术和小值的行为存在差异.

IEEE 754-1985/IEEE 754-2008标准中,小于[+/-] 2.2250738585072014E-308的64位浮点数(双)被称为非正规/非正规化/次正规数.

在iPhone 4上,这样的小数字被视为零(0),而在x86上,可以使用次正规数字进行计算.

我无法在Apple的文档Mac OS X手册页上找到有关符合IEEE-754标准的任何解释.对于float(3).

但由于对堆栈溢出(一些答案刷新到零的行为在浮点运算,双VS浮在iPhone上),我已经找到了一些线索.

根据一些搜索,似乎沿着ARM内核使用的VFP(或NEON)数学协处理器正在使用Flush-To-Zero(FTZ)模式(例如,在输出处将次正常值转换为0)和Denormals-Are-Zero( DAZ)模式(例如,当用作输入参数时,将正常值转换为0)以提供快速硬件处理的IEEE 754计算.

  • 完全符合IEEE754标准的ARM支持代码
  • 运行快速模式,符合IEEE754标准(仅限硬件)

关于FTZ和DAZ的一个很好的解释可以在IA-32中的 x87和SSE浮点辅助中找到:清零(FTZ)和非正规零(DAZ):

FTZ和DAZ模式都处理发生无效浮点数据或使用下溢或非正常条件处理的情况.[...].FTZ和DAZ处理的数字之间的差异非常微妙.FTZ处理下溢情况,而DAZ处理非正规数.当计算导致非正规时,发生下溢情况.在这种情况下,FTZ模式将输出设置为零.DAZ修复了非正规用作输入时的情况,可以是常量,也可以是将无效内存读入寄存器.DAZ模式在计算之前将计算的输入设置为零.然后可以说FTZ处理[输出]而DAZ处理[输入].

关于Apple开发者网站上FTZ的唯一内容似乎是在iOS ABI函数调用指南中:

VFP状态寄存器| FPSCR | 特别| 函数调用不保留条件代码位(28-31)和饱和位(0-4).异常控制(8-12),舍入模式(22-23)和清零到零(24)位应仅由影响应用程序状态的特定例程(包括框架API函数)修改.在函数进入和退出时,短向量长度(16-18)和步长(20-21)位必须为零.不得修改所有其他位.

根据ARM1176JZF-S技术参考手册,18.5操作模式(第一个iPhone处理器),VFP可以配置为完全支持IEEE 754(子正常算术),但在这种情况下它需要一些软件支持(陷入内核到用软件计算).

注意:我还阅读了Debian的ARM Hard Float PortVFP比较页面.

我的问题是:

  • 哪里可以找到关于跨iOS设备的次正规数处理的明确答案?

  • 是否可以设置iOS系统以支持次正规数而无需编译器仅生成完整的软件浮点代码?

谢谢.

c floating-point arm ieee-754 ios

11
推荐指数
1
解决办法
3471
查看次数

从双精度参数开始的80位扩展精度计算的属性

以下是插值函数的两种实现.争论u1始终在0.和之间1..

#include <stdio.h>

double interpol_64(double u1, double u2, double u3)
{ 
  return u2 * (1.0 - u1) + u1 * u3;  
}

double interpol_80(double u1, double u2, double u3)
{ 
  return u2 * (1.0 - (long double)u1) + u1 * (long double)u3;  
}

int main()
{
  double y64,y80,u1,u2,u3;
  u1 = 0.025;
  u2 = 0.195;
  u3 = 0.195;
  y64 = interpol_64(u1, u2, u3);
  y80 = interpol_80(u1, u2, u3);
  printf("u2: %a\ny64:%a\ny80:%a\n", u2, y64, y80);
}
Run Code Online (Sandbox Code Playgroud)

在具有80位 …

c floating-point ieee-754 extended-precision

11
推荐指数
1
解决办法
620
查看次数

SSE浮点运算是否可重复?

x87 FPU值得注意的是使用内部80位精度模式,这通常会导致编译器和机器出现意外和不可重现的结果.在我搜索 .NET上可重现的浮点数学时,我发现.NET(Microsoft和Mono)的两个主要实现都在64位模式下发出SSE指令而不是x87.

SSE(2)严格使用32位寄存器用于32位浮点数,严格使用64位寄存器用于64位浮点数.通过设置适当的控制字,可以选择将非正规数刷新为零.

因此,似乎SSE不会受到x87的精度相关问题的影响,并且唯一的变量是可以控制的非正规行为.

抛开超越函数的问题(SSE本身不像x87那样提供),是否使用SSE保证了机器和编译器之间可重现的结果?例如,编译器优化会转化为不同的结果吗?我发现了一些相互矛盾的观点:

如果您有SSE2,请使用它并从此过上幸福的生活.SSE2支持32b和64b操作,中间结果具有操作数的大小.- Yossi Kreinin,http://www.yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html

...

SSE2指令(...)完全符合IEEE754-1985标准,它们具有更好的可重复性(由于静态舍入精度)和其他平台的可移植性.Muller et aliis, Handbook of Floating-Point Arithmetic - p.107

然而:

此外,您不能将SSE或SSE2用于浮点,因为它太低于指定而不具有确定性.- John Watte http://www.gamedev.net/topic/499435-floating-point-determinism/#entry4259411

.net floating-point sse ieee-754 x87

11
推荐指数
2
解决办法
2348
查看次数

如何通过-0.0和0.0得到Python除法分别得到-Inf和Inf?

我有一种情况,即除以0.0或-0.0是合理的,我希望分别看到+ Inf和-Inf作为结果.似乎Python喜欢抛出一个

ZeroDivisionError: float division by zero
Run Code Online (Sandbox Code Playgroud)

在任一情况下.显然,我认为我可以用0.0的测试简单地包装它.但是,我找不到区分+0.0和-0.0的方法.(仅供参考,您可以通过键入或通过常见计算(例如-1.0*0.0)轻松获得-0.0.

IEEE非常好地处理了这一切,但Python似乎很难隐藏经过深思熟虑的IEEE行为.事实上,0.0 == -0.0实际上是一个IEEE功能,因此Python的行为严重破坏了事情.它在C,Java,Tcl甚至JavaScript中运行良好.

建议?

python ieee-754 divide-by-zero python-2.7

11
推荐指数
2
解决办法
1424
查看次数

最快的算法,用于识别制作双精度方程x + a == b true的最小和最大x

在静态分析的上下文中,我感兴趣的是确定x以下条件的then-branch中的值:

double x;
x = …;
if (x + a == b)
{
  …
Run Code Online (Sandbox Code Playgroud)

a并且b可以假设为双精度常量(推广到任意表达式是问题中最容易的部分),并且可以假设编译器严格遵循IEEE 754(FLT_EVAL_METHOD为0).运行时的舍入模式可以假设为最接近均匀.

如果用有理数计算是便宜的,那就很简单:x合理区间中包含的双精度数值(b - a - 0.5*ulp1(b)... b - a + 0.5*ulp2(b)) .如果b是偶数则应该包括边界,如果b是奇数则排除,并且ulp1和ulp2是两个稍微不同的"ULP"定义,如果不介意在2的幂上失去一点精度,则可以采用相同的定义.

不幸的是,使用有理数的计算可能很昂贵.考虑另一种可能性是通过二分法获得每个边界,在64个双精度加法中(每个操作决定结果的一位).获得下限和上限的128个浮点加法可能比基于数学的任何解更快.

我想知道是否有办法改进"128浮点添加"的想法.实际上我有自己的解决方案,包括更改舍入模式和nextafter调用,但我不想让任何人的风格痉挛,并使他们错过比我现在拥有的更优雅的解决方案.另外我不确定两次更改舍入模式实际上比64个浮点加法更便宜.

c floating-point ieee-754

11
推荐指数
1
解决办法
422
查看次数

IEEE浮点标准是什么(+0)+( - 0)?

我是对的,对任何浮点数的任何算术运算都是由IEEE浮点标准明确定义的吗?如果是的话,只是出于好奇,那是(+0)+(-0)什么?有没有办法在实践中用C++或其他常用的编程语言来检查这些东西?

c++ floating-point ieee-754

11
推荐指数
1
解决办法
950
查看次数

我*不*想要函数exp的正确舍入

Debian系统上的C数学库的GCC实现显然符合(IEEE 754-2008)函数的实现,这意味着舍入应始终是正确的:exp

(来自维基百科)IEEE浮点标准保证加,减,乘,除,融合乘加,平方根和浮点余数将给出无限精度运算的正确舍入结果.对于更复杂的功能,1985年标准中没有给出这样的保证,它们通常只能在最后一点内准确到达.但是,2008标准保证符合要求的实现将给出正确的舍入结果,这些结果遵循主动舍入模式; 但是,函数的实现是可选的.

事实证明,我遇到了这个功能实际上阻碍的情况,因为exp函数的确切结果通常几乎恰好处于两个连续double值(1)之间的中间位置,然后程序进行了大量的进一步计算,失去了速度高达400(!):这实际上是对我的解释(不好问:-S)问题#43530011.

(1)更确切地说,当参数exp变为(2 k + 1)×2 -53,其中k为相当小的整数(例如242)时,就会发生这种情况.特别是,所涉及的计算pow (1. + x, 0.5)倾向于exp使用这样的参数进行调用x,其数量级为2 -44.

由于正确舍入的实现在某些情况下可能非常耗时,我想开发人员也会设计一种方法来获得稍微不那么精确的结果(例如,最多只有0.6 ULP或类似的东西)对于给定范围内的每个参数值(大致)有界限...(2)

......但是怎么做?

(2)我的意思是,我只是不希望像(2 k + 1)×2 -53这样的参数的某些特殊值比相同数量级的大多数值更耗时; 但是我当然不介意参数的某些特殊值是否更快,或者如果大参数(绝对值)需要更大的计算时间.

这是一个显示现象的最小程序:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

int main (void)
 {
  int i;
  double a, c;
  c = 0;
  clock_t start = clock …
Run Code Online (Sandbox Code Playgroud)

c rounding ieee-754 exp libm

11
推荐指数
1
解决办法
330
查看次数

负零(-0.0)与正零(+0.0)相比的行为

在我的代码中,

float f = -0.0; // Negative 
Run Code Online (Sandbox Code Playgroud)

并与负零相比

f == -0.0f
Run Code Online (Sandbox Code Playgroud)

结果将是true.

float f = 0.0; // Positive
Run Code Online (Sandbox Code Playgroud)

并与负零相比

f == -0.0f
Run Code Online (Sandbox Code Playgroud)

另外,结果将是true代替false

为什么在这两种情况下都是真的?


这是一个测试它的MCVE(住在coliru上):

#include <iostream>

int main()
{
    float f = -0.0;

    std::cout<<"==== > " << f <<std::endl<<std::endl;

    if(f == -0.0f)
    {
        std::cout<<"true"<<std::endl;
    }
    else
    {
        std::cout<<"false"<<std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

==== > -0  // Here print negative zero

true
Run Code Online (Sandbox Code Playgroud)

c++ floating-point ieee-754

11
推荐指数
3
解决办法
6574
查看次数

标签 统计

ieee-754 ×10

floating-point ×7

c ×4

c++ ×2

.net ×1

arm ×1

divide-by-zero ×1

exp ×1

extended-precision ×1

ios ×1

libm ×1

perl ×1

python ×1

python-2.7 ×1

rounding ×1

sse ×1

x87 ×1