C中除法的逆?
Inverse of division in C?
我想在C中做这个除法
#include <stdio.h>
void main() {
float result;
int val;
val = 7;
result = 1/(1 >> val);
}
但我得到的结果是 -2147483648 而不是 128。
这个除法如何得到正确的结果?
(1 >> val)
将 1
“向下”移动(朝向最低有效位)val
(7) 步。
要获得 128
,您需要将其“向上”移动(朝向最高有效位)val
步。
result = 1 / (1 << val);
现在你有 1 / 128
......这是 0
。为什么?因为它们都是整数。 result
是 float
并不重要。要将除法提升为两个 float
的除法,您需要将任一操作数设为 float
。然后另一个操作数也将隐式转换为 float
。
result = 1.f / (1 << val);
result
现在大约是 0.007812
.
val = 7;
1 >> val;
上面说的是将值 1 右移 7 个位置。结果会是0
因此,
result = 1/(1 >> val);
result=1/0 这是未定义的情况。这样结果就会出错
你走在正确的轨道上,1/(1/128) = 128,但你不能用右移代替除法 (x/2 = x>>1),因为它会立即移动你的1 从 lsbit 结束。
对于 C,它用零填充(在这种情况下)。因此,正如指出的那样,1/0 是未定义的,或者在浮动中是“正确签名的无穷大”或错误。在此除以零后,您将升级为浮动。
现在你可以做到这一点,并让它与你自己的浮点数一起工作,例如你说把点放在第 15 位和第 16 位之间。让你自己来调整。
对于浮点数 (IEEE 754),您不能直接将它移位,将 1 变成 1/128 也不能移位。您调整指数并保留分数。
所以这可以用定点数学来完成没问题,只是不像你这里有的那样。
要查看问题,请执行此操作
for(y=0,x=0x80;y<20;x>>=1,y++)
{
printf("0x%02X %u\n",x,y);
}
在您的情况下,1>>7 以 0x01 开头,您也可以使用 x=0x01 重复该实验,看看会发生什么。
你做了除以零,你得到了编译器为你提供的结果(认为是编译器而不是硬件)。
你的编译器没有抱怨吗?
test.c:5:17: warning: division by zero [-Wdiv-by-zero]
5 | return(float)(1/(1>>7));
|
我想在C中做这个除法
#include <stdio.h>
void main() {
float result;
int val;
val = 7;
result = 1/(1 >> val);
}
但我得到的结果是 -2147483648 而不是 128。 这个除法如何得到正确的结果?
(1 >> val)
将 1
“向下”移动(朝向最低有效位)val
(7) 步。
要获得 128
,您需要将其“向上”移动(朝向最高有效位)val
步。
result = 1 / (1 << val);
现在你有 1 / 128
......这是 0
。为什么?因为它们都是整数。 result
是 float
并不重要。要将除法提升为两个 float
的除法,您需要将任一操作数设为 float
。然后另一个操作数也将隐式转换为 float
。
result = 1.f / (1 << val);
result
现在大约是 0.007812
.
val = 7;
1 >> val;
上面说的是将值 1 右移 7 个位置。结果会是0 因此,
result = 1/(1 >> val);
result=1/0 这是未定义的情况。这样结果就会出错
你走在正确的轨道上,1/(1/128) = 128,但你不能用右移代替除法 (x/2 = x>>1),因为它会立即移动你的1 从 lsbit 结束。
对于 C,它用零填充(在这种情况下)。因此,正如指出的那样,1/0 是未定义的,或者在浮动中是“正确签名的无穷大”或错误。在此除以零后,您将升级为浮动。
现在你可以做到这一点,并让它与你自己的浮点数一起工作,例如你说把点放在第 15 位和第 16 位之间。让你自己来调整。
对于浮点数 (IEEE 754),您不能直接将它移位,将 1 变成 1/128 也不能移位。您调整指数并保留分数。
所以这可以用定点数学来完成没问题,只是不像你这里有的那样。
要查看问题,请执行此操作
for(y=0,x=0x80;y<20;x>>=1,y++)
{
printf("0x%02X %u\n",x,y);
}
在您的情况下,1>>7 以 0x01 开头,您也可以使用 x=0x01 重复该实验,看看会发生什么。
你做了除以零,你得到了编译器为你提供的结果(认为是编译器而不是硬件)。
你的编译器没有抱怨吗?
test.c:5:17: warning: division by zero [-Wdiv-by-zero]
5 | return(float)(1/(1>>7));
|