标签: ieee-754

为什么(inf + 0j)* 1计算为inf + nanj?

>>> (float('inf')+0j)*1
(inf+nanj)
Run Code Online (Sandbox Code Playgroud)

为什么?这在我的代码中造成了一个讨厌的错误。

为什么1乘法身份不给(inf + 0j)

python nan ieee-754

93
推荐指数
3
解决办法
3381
查看次数

安静的NaN和信号NaN有什么区别?

我读过关于浮点的内容,我知道NaN可能来自操作.但我无法完全理解这些概念是什么.有什么区别?

在C++编程期间可以生成哪一个?作为程序员,我可以编写一个程序来导致sNaN吗?

floating-point nan ieee-754

81
推荐指数
2
解决办法
2万
查看次数

在16位,32位和64位IEEE-754系统中可以表示哪些数字?

我知道浮点数是如何表示的,但是还不够,我害怕.

一般问题是:

对于给定的精度(对于我的目的,基数10中的精确小数位数),可以为16位,32位和64位IEEE-754系统表示什么范围的数字?

具体来说,我只对16位和32位数字的范围感兴趣,精确到+/- 0.5(那些位置)或+/- 0.0005(千分位数).

floating-point precision numerical ieee-754

71
推荐指数
4
解决办法
7万
查看次数

什么是次正规浮点数?

isnormal()参考页面告诉:

确定给定的浮点数arg是否正常,即既不是零,也不是正常,无限,也不是NaN.

数字为零,无限或NaN很清楚它意味着什么.但它也说低于正常.什么时候是一个数字次正常?

c++ floating-point ieee-754 c++11

65
推荐指数
3
解决办法
2万
查看次数

格式化C#中输出的双精度数

在.NET中运行与双倍乘法相关的快速实验并阅读了几篇关于C#字符串格式的文章,我认为这样:

{
    double i = 10 * 0.69;
    Console.WriteLine(i);
    Console.WriteLine(String.Format("  {0:F20}", i));
    Console.WriteLine(String.Format("+ {0:F20}", 6.9 - i));
    Console.WriteLine(String.Format("= {0:F20}", 6.9));
}
Run Code Online (Sandbox Code Playgroud)

将是这个C代码的C#等价物:

{
    double i = 10 * 0.69;

    printf ( "%f\n", i );
    printf ( "  %.20f\n", i );
    printf ( "+ %.20f\n", 6.9 - i );
    printf ( "= %.20f\n", 6.9 );
}
Run Code Online (Sandbox Code Playgroud)

但是C#会产生输出:

6.9
  6.90000000000000000000
+ 0.00000000000000088818
= 6.90000000000000000000
Run Code Online (Sandbox Code Playgroud)

尽管我在调试器中显示的值等于6.89999999999999946709(而不是6.9).

与C比较,显示格式要求的精度:

6.900000                          
  6.89999999999999946709          
+ 0.00000000000000088818          
= 6.90000000000000035527          
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

(Microsoft .NET Framework版本3.51 SP1/Visual …

c# floating-point formatting ieee-754

62
推荐指数
5
解决办法
11万
查看次数

所有整数值都完美地表示为双精度数吗?

我的问题是,是否保证所有整数值都具有完美的双重表示.

请考虑以下打印"相同"的代码示例:

// Example program
#include <iostream>
#include <string>

int main()
{
  int a = 3;
  int b = 4;
  double d_a(a);
  double d_b(b);

  double int_sum = a + b;
  double d_sum = d_a + d_b;

  if (double(int_sum) == d_sum)
  {
      std::cout << "Same" << std::endl;
  }
}
Run Code Online (Sandbox Code Playgroud)

对于任何架构,任何编译器,任何值ab?保证这是真的吗?i转换为的任何整数是否double总是表示为i.0000000000000和不表示为,例如,i.000000000001

我尝试了其他一些数字并且它总是如此,但无法找到关于这是巧合还是设计的任何信息.

注意:这与这个问题(除了语言)不同,因为我添加了两个整数.

c++ precision double standards ieee-754

57
推荐指数
3
解决办法
8693
查看次数

大量错误地在JavaScript中舍入

看到这段代码:

<html>
  <head> 
    <script src="http://www.json.org/json2.js" type="text/javascript"></script>
    <script type="text/javascript">

      var jsonString = '{"id":714341252076979033,"type":"FUZZY"}';
      var jsonParsed = JSON.parse(jsonString);
      console.log(jsonString, jsonParsed);

    </script>
  </head>
  <body>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

当我在Firefox 3.5中看到我的控制台时,jsonParsed的值是:

Object id=714341252076979100 type=FUZZY
Run Code Online (Sandbox Code Playgroud)

即数字四舍五入.尝试了不同的值,相同的结果(数字舍入).

我也没有得到它的舍入规则.714341252076979136舍入为714341252076979200,而714341252076979135舍入为714341252076979100.

编辑:请参阅下面的第一条评论.显然这不是关于JSON,而是关于JavaScript数字处理的东西.但问题仍然存在:

为什么会这样?

javascript floating-point floating-accuracy ieee-754

55
推荐指数
4
解决办法
3万
查看次数

NaN的位模式是否真的依赖于硬件?

我正在阅读Java语言规范中的浮点NaN值(我很无聊).32位float具有此位格式:

seee eeee emmm mmmm mmmm mmmm mmmm mmmm
Run Code Online (Sandbox Code Playgroud)

s是符号位,e是指数位,m是尾数位.NaN值被编码为所有1的指数,并且尾数位不是全0(其将是+/-无穷大).这意味着存在许多不同的可能NaN值(具有不同的sm位值).

在此,JLS§4.2.3说:

IEEE 754为其单浮点格式和双浮点格式提供了多个不同的NaN值.虽然每个硬件架构在生成新的NaN时返回NaN的特定位模式,但是程序员也可以创建具有不同位模式的NaN以编码例如回顾性​​诊断信息.

JLS中的文本似乎意味着,例如,结果0.0/0.0具有依赖于硬件的位模式,并且取决于该表达式是否被计算为编译时常量,它依赖的硬件可能是硬件编译Java程序或运行程序的硬件.如果这是真的,这一切似乎都很脆弱.

我运行了以下测试:

System.out.println(Integer.toHexString(Float.floatToRawIntBits(0.0f/0.0f)));
System.out.println(Integer.toHexString(Float.floatToRawIntBits(Float.NaN)));
System.out.println(Long.toHexString(Double.doubleToRawLongBits(0.0d/0.0d)));
System.out.println(Long.toHexString(Double.doubleToRawLongBits(Double.NaN)));
Run Code Online (Sandbox Code Playgroud)

我机器上的输出是:

7fc00000
7fc00000
7ff8000000000000
7ff8000000000000
Run Code Online (Sandbox Code Playgroud)

输出显示没有超出预期.指数位都是1.尾数的高位也是1,对于NaN,它显然表示"安静的NaN"而不是"信号NaN"(https://en.wikipedia.org/wiki/NaN# Floating_point).符号位和尾数位的其余部分为0.输出还显示我的机器上生成的NaN与Float和Double类的常量NaN之间没有差异.

我的问题是,无论编译器或虚拟机的CPU是什么,在Java中都能保证输出,还是真的无法预测?JLS对此很神秘.

如果保证输出0.0/0.0,是否有任何算法生成具有其他(可能依赖于硬件?)位模式的NaN?(我知道intBitsToFloat/ longBitsToDouble可以编码其他NaN,但我想知道其他值是否可以从正常算术中发生.)


后续要点:我注意到Float.NaNDouble.NaN指定了它们的确切位模式,但是在源(Float,Double)中它们是由它们生成的0.0/0.0.如果该划分的结果实际上取决于编译器的硬件,那么在规范或实现中似乎存在缺陷.

java floating-point nan ieee-754

55
推荐指数
4
解决办法
3178
查看次数

这个浮点平方根逼近是如何工作的?

我找到了一个相当奇怪但工作的平方根逼近floats; 我真的不明白.有人能解释一下为什么这段代码有效吗?

float sqrt(float f)
{
    const int result = 0x1fbb4000 + (*(int*)&f >> 1);
    return *(float*)&result;   
}
Run Code Online (Sandbox Code Playgroud)

我测试了一下它输出的值std::sqrt()约为1到3%.我知道Quake III的快速反平方根,我想这里有类似的东西(没有牛顿迭代),但我真的很感激它的工作原理.

(nota:我已经用标记了它,因为它既有效-ish(见注释)C和C++代码)

c c++ floating-point optimization ieee-754

51
推荐指数
4
解决办法
3759
查看次数

信号NaN的有用性?

我最近读了很多关于IEEE 754和x87架构的内容.我正在考虑在我正在研究的一些数值计算代码中使用NaN作为"缺失值",我希望使用信令 NaN将允许我在我不想要的情况下捕获浮点异常继续"缺失值".相反,我会使用安静的 NaN来允许"缺失值"通过计算传播.但是,信号NaN不起作用,因为我认为它们将基于它们上存在的(非常有限的)文档.

以下是我所知道的摘要(所有这些都使用x87和VC++):

  • _EM_INVALID(IEEE"无效"异常)在遇到NaN时控制x87的行为
  • 如果屏蔽了_EM_INVALID(禁用了异常),则不会生成异常,操作可以返回安静的NaN.涉及信令NaN的操作不会引发异常,但会转换为安静的NaN.
  • 如果_EM_INVALID未被屏蔽(启用了异常),则无效操作(例如,sqrt(-1))会导致抛出无效异常.
  • x87 从不生成信令NaN.
  • 如果_EM_INVALID是未屏蔽的,任何使用的信令的NaN(即使初始化与它的变量)的导致一个无效引发异常.

标准库提供了一种访问NaN值的方法:

std::numeric_limits<double>::signaling_NaN();
Run Code Online (Sandbox Code Playgroud)

std::numeric_limits<double>::quiet_NaN();
Run Code Online (Sandbox Code Playgroud)

问题是我认为信号NaN没有任何用处.如果屏蔽了_EM_INVALID,则其行为与安静NaN完全相同.由于没有NaN与任何其他NaN相当,因此没有逻辑差异.

如果屏蔽_EM_INVALID (启用异常),则甚至无法使用信号NaN初始化变量: double dVal = std::numeric_limits<double>::signaling_NaN();因为这会引发异常(信号NaN值被加载到x87寄存器以将其存储到存储器地址).

您可以像我一样思考以下内容:

  1. 掩码_EM_INVALID.
  2. 使用信令NaN初始化变量.
  3. Unmask_EM_INVALID.

但是,步骤2会导致信令NaN转换为安静的NaN,因此后续使用它不会导致异常被抛出!那么WTF?!

信号NaN是否有任何实用性或目的?我理解其中一个原始意图是使用它初始化内存,以便可以捕获使用单位化浮点值.

有人能告诉我,如果我在这里遗失了什么吗?


编辑:

为了进一步说明我希望做的事情,这里有一个例子:

考虑对数据向量(双精度)执行数学运算.对于某些操作,我想允许向量包含"缺失值"(假设这对应于电子表格列,例如,其中一些单元格没有值,但它们的存在很重要).对于某些操作,我希望允许向量包含"缺失值".如果集合中存在"缺失值",也许我想采取不同的行动 - 可能执行不同的操作(因此这不是无效的状态).

这个原始代码看起来像这样:

const double MISSING_VALUE = 1.3579246e123;
using std::vector;

vector<double> missingAllowed(1000000, MISSING_VALUE);
vector<double> missingNotAllowed(1000000, MISSING_VALUE);

// ... populate missingAllowed and missingNotAllowed with (user) data...

for (vector<double>::iterator it = missingAllowed.begin(); it != missingAllowed.end(); ++it) …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point ieee-754 visual-c++ x87

50
推荐指数
1
解决办法
1万
查看次数