我怎样才能手动设置一个浮点数的值相当于NaN? [英] How can I manually set the bit value of a float that equates to NaN?

查看:566
本文介绍了我怎样才能手动设置一个浮点数的值相当于NaN?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图运行一些测试与转换和浮点数的铸件到其他类型,我想设置我的浮点变量为nan的不同值。



IEEE浮点标准单精度(32位)NaN的按位示例为:s111 1111 1axx xxxx xxxx xxxx xxxx xxxx其中s是符号(在应用程序中经常被忽略),a决定NaN的类型,x是一个额外的有效负载(在应用程序中最常被忽略),如果a = 1,那么它是一个安静的NaN;如果a为零,且有效负载不为零,那么它是一个信号NaN。 b

基本上我想找到一种方法来设置表示的有效载荷或xxxx。有没有办法做到这一点在C?您可能能够通过传递适当的字符串来控制'有效载荷'位到C99 nan nanf nanl 函数,但是这些函数只会生成 quiet NaNs,字符串是未指定的(大多数实现将其视为十六进制数字)。

或者,使用联合:

  #ifndef __STDC_IEC_559__ 
#error这个程序需要IEEE浮点运算
#endif

#include ;
#include< assert.h>
$ b $ static_assert(sizeof(float)== sizeof(uint32_t),
这个程序需要浮点数为32位);

float nanf_with_payload_bits(uint32_t payload)
{
if(payload& 0x7FA00000)abort();

union ieee_single {
float f;
uint32_t i;
} nan;

nan.i = 0x7FA00000 |有效载荷;
返回nan.f;





$ b

写入一个联合的一个成员然后从另一个联合中读取,大小完全相同,不会在C99 +勘误中引发未定义的行为。 (在C89中 是未定义的行为,但是大多数编译器都将它定义为按照你期望的方式进行操作,在C ++中它仍然是未定义的行为,我不确定;但是大多数编译器再次定义它如果你使用这个函数来创建信号NaNs,请注意它们的行为是明确地保留了未定义的C99 / C11附录F。

不要尝试将联合的 i 组件分解为一个结构位字段。结构内的位字段的存储器布局部分是实现定义的并且是部分未指定的,并且特别是一个位字段序列不是必须按照与CPU端序列相同的顺序打包到一个字中(或者确实包装妥当)。






标准引用(全部为C99):


  • 这个union的使用只是 unspecified 行为:6.2.6.1p7; J.1

  • 结构中的位域布局是不可预知的:6.2.6.1p1,2; 6.7.2.1p10,11,13; J.3.9
  • 信号NaNs的行为是未定义的:F.2.1

I'm trying to run some tests with conversions and castings of floats to other types and I want to set my float variable to different values of nan.

"a bit-wise example of a IEEE floating-point standard single precision (32-bit) NaN would be: s111 1111 1axx xxxx xxxx xxxx xxxx xxxx where s is the sign (most often ignored in applications), a determines the type of NaN, and x is an extra payload (most often ignored in applications). If a = 1, it is a quiet NaN; if a is zero and the payload is nonzero, then it is a signaling NaN"

Basically I want to find a way to set the payload or xxxx's of the representation. Is there any way to do this in c?

解决方案

You may be able to control the 'payload' bits by passing appropriate strings to the C99 nan, nanf, nanl functions, but these will only generate quiet NaNs, and the interpretation of the string is left unspecified (most implementations treat it as a hexadecimal number).

Alternatively, use a union:

#ifndef __STDC_IEC_559__
#error "This program requires IEEE floating point arithmetic"
#endif

#include <stdint.h>
#include <assert.h>

static_assert(sizeof(float) == sizeof(uint32_t),
    "This program requires float to be 32 bits exactly");

float nanf_with_payload_bits(uint32_t payload)
{
   if (payload & 0x7FA00000) abort();

   union ieee_single {
       float f;
       uint32_t i;
   } nan;

   nan.i = 0x7FA00000 | payload;
   return nan.f;
}

Writing to one member of a union and then reading from another, when both types are exactly the same size, does NOT provoke undefined behavior in C99+errata. (It was undefined behavior in C89, but most compilers defined it to do what you would expect. It may still be undefined behavior in C++, I'm not sure; however, again, most compilers define it to do what you would expect.)

If you use this function to create signaling NaNs, be aware that their behavior is explicitly left undefined in C99/C11 Annex F.

DO NOT attempt to break down the i component of the union into a structure with bit-fields. The memory layout of bit-fields within a structure is partially implementation-defined and partially unspecified, and in particular a sequence of bit-fields is not necessarily packed into a word in the same order as the CPU endianness (or, indeed, properly packed at all).


Standards citations (all C99):

  • this use of a union is only unspecified behavior: 6.2.6.1p7; J.1
  • the layout of bitfields within a structure is unpredictable: 6.2.6.1p1,2; 6.7.2.1p10,11,13; J.3.9
  • the behavior of signaling NaNs is undefined: F.2.1

这篇关于我怎样才能手动设置一个浮点数的值相当于NaN?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆