标签: ieee-754

为什么c/c ++浮点类型如此奇怪的命名?

C++提供了三种浮点类型:float,double和long double.我不经常在我的代码中使用浮点数,但是当我这样做时,我总是被类似无害线路上的警告所困扰

float PiForSquares = 4.0;
Run Code Online (Sandbox Code Playgroud)

问题是文字4.0是双重的,而不是浮动的 - 这很刺激.

对于整数类型,我们有short int,int和long int,这非常简单.为什么C不具有短浮动,浮动和长浮动?在地球上"双重"来自哪里?

编辑:浮动类型之间的关系似乎与整数类似.double必须至少与float一样大,而long double至少与double一样大.没有其他精度/范围的保证.

c c++ floating-point history ieee-754

15
推荐指数
3
解决办法
8351
查看次数

浮点到二进制值(C++)

我想在C++中使用浮点数,如2.25125,以及填充二进制值的int数组,该值用于将浮点数存储在内存中(IEEE 754).

所以我可以取一个数字,最后得到一个int num [16]数组,其二进制值为float:num [0]将是1 num [1]将是1 num [2]将是0 num [3 ]将是1等等......

将int放入数组并不困难,只需获取float的二进制值的过程就是我被困住的地方.你能不能在内存中读取float变量的二进制文件?如果没有,我怎么能用C++做这个呢?

编辑:这种方式进行比较的原因是我想学习在C++中进行逐位运算.

c++ floating-point binary ieee-754

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

80位扩展精度数据类型有哪些应用/优点?

是的,我的意思是说80位.这不是一个错字......

我对浮点变量的经验总是涉及4字节的倍数,如单音(32位),双音(64位)和长双音(我已经看到它被称为96位或128位).这就是为什么当我遇到一些代码来读取和写入AIFF(音频交换文件格式)文件时遇到80位扩展精度数据类型时我有点困惑:选择了一个扩展精度变量来存储采样音轨的速率.

当我浏览维基百科时,我发现上面的链接以及IEEE 754-1985标准摘要中的80位格式的简要提及(但不在IEEE 754-2008标准摘要中).看来,在某些架构上,"扩展"和"长双"是同义词.

我没有遇到的一件事是使用扩展精度数据类型的特定应用程序(当然,AIFF文件采样率除外).这让我想知道:

  • 有没有人遇到过扩展精度对某些编程应用来说是必要/有益的情况?
  • 80位浮点数有什么好处,除了显而易见的"它比双倍的精度稍高但比大多数长双精度的实现更少"?
  • 它的适用性正在减弱吗?

floating-point ieee-754

15
推荐指数
3
解决办法
5440
查看次数

如何检查float是否可以精确表示为整数

我正在寻找一种合理有效的方法来确定浮点值(double)是否可以由整数数据类型(long,64位)精确表示.

我最初的想法是检查指数是否0(或更确切地说127).但这不会起作用,因为2.0e = 1 m = 1 ......

基本上,我被卡住了.我有一种感觉,我可以使用位掩码做到这一点,但我现在还没有理解如何做到这一点.

那么我怎样才能检查一个double是否完全可以表示为long?

谢谢

c double ieee-754

15
推荐指数
2
解决办法
3816
查看次数

当另一个公式似乎更有意义时,为什么基于表格的sin近似文献总是使用这个公式?

关于sin用表格计算基本函数的文献参考公式:

sin(x) = sin(Cn) * cos(h) + cos(Cn) * sin(h)
Run Code Online (Sandbox Code Playgroud)

其中x = Cn + h,Cn是针对其恒定sin(Cn)cos(Cn)已被预先计算并在表中可用的,并且,如果以下半乳糖的方法,Cn已被选择为使得两个sin(Cn)cos(Cn)密切由浮点数近似.数量h接近0.0.此公式的参考示例是本文(第7页).

我不明白为什么这是有道理的:cos(h)然而,它被计算,对于某些值,至少0.5 ULP可能是错误的h,并且因为它接近1.0,这似乎对结果的准确性有极大的影响.sin(x)以这种方式计算.

我不明白为什么不使用下面的公式:

sin(x) = sin(Cn) + (sin(Cn) * (cos(h) - 1.0) + cos(Cn) * sin(h))
Run Code Online (Sandbox Code Playgroud)

然后两个量(cos(h) - 1.0),并sin(h)可以用,很容易做出准确的,因为它们产生接近零的结果多项式来近似.为价值观sin(Cn) * (cos(h) - 1.0), cos(Cn) * sin(h)并为他们的总和仍然很小,其绝对精度,该总和表示,因此,加入这个量的少量ULPS表达sin(Cn)几乎是正确舍入. …

floating-point ieee-754 elementary-functions

15
推荐指数
2
解决办法
765
查看次数

是否有IEEE-754操作的开源c/c ++实现?

我正在寻找IEEE-754操作的参考实现.有这样的事吗?

c++ floating-point open-source ieee-754

14
推荐指数
2
解决办法
9080
查看次数

为什么pow(-infinity,正非整数)+无限?

C99附件F(IEEE浮点支持)说:

pow(??, y) y> 0时返回+∞而不是奇数.

但是,比方说,( - ∞)0.5实际上有虚数值±∞i,而不是+∞.C99自己sqrt(??)返回NaN并按预期生成域错误.为什么然后pow需要返回+∞?

(大多数其他语言直接使用C库,或者像本例中的Python一样,通过标准复制它所需的行为,因此在实践中这不仅仅影响C99.)

c math floating-point standards ieee-754

14
推荐指数
1
解决办法
485
查看次数

非规范化数字 - IEEE 754浮点数

因此,我试图了解更多关于浮点数的IEEE 754标准中定义的非规范化数字.由于Google搜索结果,我已经阅读了几篇文章,并且我已经阅读了几篇StackOverFlow帖子.但是我还有一些问题没有答案.

首先,回顾一下我对Denormalized float的理解:

具有较少精度位的数字,并且比标准化数字更小(数量级)

实质上,非规范化浮点数能够表示可以用任何浮点值表示的SMALLEST(幅度)数.

这听起来不对吗?还有什么呢?

我读过:

使用非规范化数字会在许多平台上带来性能成本

对此有何评论?

我也读过其中一篇文章

一个应该"避免规范化和非规范化数字之间的重叠"

对此有何评论?

在IEEE标准的一些演示中,当呈现浮点范围时,排除非规格化值并将表标记为"有效范围",几乎就像演示者正在思考"我们知道非规范化数字CAN表示可能的最小浮动点值,但由于非规范化数字的某些缺点,我们选择将它们从更适合常见使用场景的范围中排除" - 好像非常规化数字不常用.

我想我一直认为在大多数情况下使用非规范化数字并不是一件好事?

如果我必须自己回答这个问题,我会想:

使用非规格化数字是好的,因为您可以表示可能的最小(数量级)数字 - 只要精度不重要,并且您不将它们与标准化数字混合,并且应用程序的最终性能符合要求.

使用非规范化数字是一件坏事,因为大多数应用程序不需要如此小的表示 - 精确损失是有害的,并且你可以通过将它们与标准化数字混合来轻松地射击自己,并且性能不值得花费在多数情况下.

对这两个答案有何评论?还有哪些我可能会丢失或不理解非规范化数字?

floating-point performance standards ieee-754

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

融合乘法加法和默认舍入模式

使用GCC 5.3,以下代码符合 -O3 -fma

float mul_add(float a, float b, float c) {
  return a*b + c;
}
Run Code Online (Sandbox Code Playgroud)

生成以下程序集

vfmadd132ss     %xmm1, %xmm2, %xmm0
ret
Run Code Online (Sandbox Code Playgroud)

我注意到GCC -O3已经在GCC 4.8中这样做了.

Clang 3.7带-O3 -mfma产品

vmulss  %xmm1, %xmm0, %xmm0
vaddss  %xmm2, %xmm0, %xmm0
retq
Run Code Online (Sandbox Code Playgroud)

但Clang 3.7与-Ofast -mfmaGCC生成的代码相同-O3 fast.

我很惊讶GCC的确如此,-O3因为从这个答案来看

除非允许使用宽松的浮点模型,否则不允许编译器融合分离的加法和乘法.

这是因为FMA只有一个舍入,而ADD + MUL有两个舍入.因此,编译器将通过融合违反严格的IEEE浮点行为.

但是,从这个链接

无论FLT_EVAL_METHOD的值如何,任何浮点表达式都可以收缩,即,计算好像所有中间结果都具有无限范围和精度.

所以现在我感到困惑和担忧.

  1. GCC是否有理由使用FMA -O3
  2. 融合是否违反了严格的IEEE浮点行为?
  3. 如果融合确实违反了IEEE浮点运算,那么GCC的回归__STDC_IEC_559__不是一个矛盾吗?

由于FMA 可以在软件中进行仿真,因此似乎应该有两个用于FMA的编译器开关:一个用于告诉编译器在计算中使用FMA,一个用于告诉编译器硬件具有FMA.


显然,这可以通过选项进行控制-ffp-contract.对于GCC,默认是-ffp-contract=fast和Clang不一样.其他选项例如 …

c gcc clang ieee-754 fma

14
推荐指数
1
解决办法
1347
查看次数

通过计算得不到0.30000000000000004

当我在控制台中运行时,0.1 + 0.2结果是0.30000000000000004.所以我试着自己计算一下.以下是我采取的步骤.

1)表示0.1为IEEE754双:

0.1 = 0 01111111011 1001100110011001100110011001100110011001100110011010
Run Code Online (Sandbox Code Playgroud)

2)表示0.2为IEEE754双:

0.2 = 0 01111111100 1001100110011001100110011001100110011001100110011010
Run Code Online (Sandbox Code Playgroud)

这里的计算应该是正确的,因为我已经使用我的自定义函数检查了它们,该函数显示了JavaScript如何存储数字.

3)将两个数字转换为科学记数法:

0.1 = 1.1001100110011001100110011001100110011001100110011010x 2-4

0.2 = 1.1001100110011001100110011001100110011001100110011010x 2-3

现在由于指数数字不同,让我们调整0.2-4:

0.2 = 0.11001100110011001100110011001100110011001100110011010x 2-4

4)添加它们:

  1.1001100110011001100110011001100110011001100110011010
+ 0.1100110011001100110011001100110011001100110011001101
  ------------------------------------------------------
 10.0110011001100110011001100110011001100110011001100111
Run Code Online (Sandbox Code Playgroud)

所以总和是:

10.0110011001100110011001100110011001100110011001100111x 2-4

5)将其标准化:

1.00110011001100110011001100110011001100110011001100111x 2-3

6)在小数点后将其四舍五入:

1.1100110011001100110011001100110011001100110011010000x 2-3

删除指数后,我最终得到以下结果数:

0.001110011001100110011001100110011001100110011001101 
Run Code Online (Sandbox Code Playgroud)

当我使用此计算器将其转换为十进制时,它显示:

0.225000000000000088817841970012523233890533447265625
Run Code Online (Sandbox Code Playgroud)

不完全是预期的 …

javascript binary ieee-754

14
推荐指数
1
解决办法
247
查看次数