Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c中的否定浮点数在某些情况下会失败_C_Bit Manipulation - Fatal编程技术网

c中的否定浮点数在某些情况下会失败

c中的否定浮点数在某些情况下会失败,c,bit-manipulation,C,Bit Manipulation,我写了一个函数,它适用于数百种情况,但在某些情况下失败 下面是C函数: unsigned negate_number(unsigned x) { int sign = (!(x & 0x80000000))<<31; int other = 0x7FFFFFFF & x; return (sign | other); } unsigned negate_数(unsigned x){ 整数符号=(!(x&0x8000000))我问: 当代码处理整数时,为什

我写了一个函数,它适用于数百种情况,但在某些情况下失败

下面是C函数:

unsigned negate_number(unsigned x) {
  int sign = (!(x & 0x80000000))<<31;
  int other = 0x7FFFFFFF & x;
  return (sign | other);
}
unsigned negate_数(unsigned x){
整数符号=(!(x&0x8000000))我问:


当代码处理整数时,为什么要问标题中的“浮点数”问题?你是否试图用
float
调用函数,并或多或少地将其视为一个位数组?如果是这样,你就处于隐藏状态!如果你在作用域中使用原型调用函数,C编译器将转换
float
如果不在作用域中使用原型调用它,C编译器将在调用函数之前将
浮点
转换为
双精度

答复是:


这是一个32位的IEEE 754单精度数字。所以我只是翻转最重要的位(符号位)

要翻转32位(无符号整数)量的最高有效位,只需编写:

x ^= 0x80000000;
然而,正如我所指出的,除非你对你的编译器撒谎,否则你不会通过一个32位的
浮点值

伪代码 文件A.c 文件B.c 然而,你在玩火,向你的编译器撒谎。编译器讨厌被欺骗,并且经常找到一种方法来找回自己。不要这样做!

主要是犹太法典 要以最少的问题(而不是“无问题”)或多或少达到您想要的效果,您可能需要:

文件B.c 严格地说,在分配给
u.y
后读取和写入
u.x
是未定义的行为,但它通常会执行您想要的操作;同样,在操作
u.x
后返回
u.y


所有这些都假设
浮点
无符号
的位布局是这样的:
浮点
的符号位是
无符号
的最高有效位

当代码处理整数时,为什么要在标题中询问“浮点数”?是否尝试使用调用函数e> 浮点数
并或多或少地将其视为一个位数组?如果是这样,你就处于一个“无隐藏”状态!如果你在作用域中使用原型调用函数,C编译器将把
浮点数
转换为
无符号整数
。如果你不在作用域中使用原型调用它,C编译器将
浮点数
转换为
>在调用函数之前双击。它是一个32位IEEE 754单精度数字。因此我只是翻转最高有效位(符号位)。这对NaN(不是数字)失败输入。在这些情况下,如何使其具有故障安全性?@Anon如果您对NaN符号进行补码,它仍然是NaN-除非其他代码被破坏并且无法检测到这种NaN。我不能使用浮点作为类型。我必须使用无符号int作为类型。但输入将是32位单精度浮点数(IEEE 754)。您不理解我写的内容。函数的输入不能是32位的
浮点
。您可以在调用代码中执行
联合
操作,并将
u.x
传递给您的函数。您也可以在
否定编号()
中执行
联合
操作。但您不能以编写代码的方式执行此操作。(或者,至少,我不认为您可以用编写代码的方式来完成。)[…继续…][…继续…]现在,如果调用代码中有一个
unsigned
,其中包含与某个
float
值相对应的位模式,那么当然可以将该
unsigned int
传递给带有
unsigned
参数和
unsigned
返回值的函数,然后可以使用
negate\u num的版本ber()
标记为“伪”。但您应该清楚,您传递的是一个
无符号的
(它恰好包含与某些
浮点值相同的位模式),而不是
浮点值本身。是的,输入是无符号的整数,它包含一些相应的浮点值,包括Nan(不是数字)如果将作为输入抛出,则需要返回。确定;因此您正在传递
无符号的
值。您的问题应该更清楚!根据,您可以翻转NaN的符号位,而不会真正影响它。如果您不想尝试(或冒风险)更改NaN,请检测NaN模式
((x&0x7F100000)==0x7F100000)
并保持值不变。
extern float negate_number(float x);

...
float f1 = 3.14159;
float f2 = negate_number(f1);
...
unsigned negate_number(unsigned x)
{
    return x ^ 0x80000000;
}
float negate_number(float f)
{
    union { unsigned x; float y; } u;
    u.y = f;
    u.x ^= 0x80000000;
    return u.y;
}