我疯了,为什么我的变量对我变了
Going crazy, why are my variables changing on me?
好吧,我有这种情况发生在我之前,其中变量随机改变数字,因为内存分配问题或错误的寻址等,比如当你走了边界与数组。然而,我没有使用数组,或指针或地址,所以我不知道为什么在执行这个循环后,它突然决定"指数"设置为0
后等于循环内的288
:
EDIT:它决定在特定的:0x80800000
上中断。
这不会在一个测试中中断,我们有一个"测试"客户端,它迭代了几个测试用例,每次它再次调用这个,每次函数被再次调用时,值应该被设置为等于它们的原始值。
/*
* float_i2f - Return bit-level equivalent of expression (float) x
* Result is returned as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point values.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned float_i2f(int x) {
int sign= 0;
int a=0;
int exponent=0;
int crash_test=0;
int exp=0;
int fraction=0;
int counter=0;
if (x == 0) return 0;
if (!(x ^ (0x01 << 31)))
{
return 0xCF << 24;
}
if (x>>31)
{
sign = 0xFF << 31;
x = (~x) + 1;
}
else
{
sign = 0x00;
}
//printf(" After : %x ", x);
a = 1;
exponent = 0;
crash_test = 0;
while ((a*2) <= x)
{
if (a == 0) a =1;
if (a == 1) crash_test = exponent;
/*
if(exponent == 288)
{exponent =0;
counter ++;
if(counter <=2)
printf("WENT OVERBOARD WTF %d ORIGINAL %d", a, crash_test);
}
*/
if (exponent > 300) break;
exponent ++;
a *= 2;
}
exp = (exponent + 0x7F) << 23;
fraction = (~(((0x01)<< 31) >> 7)) & (x << (25 - (exponent + 1)));
return sign | exp | fraction;
}
使用调试器或IDE,对指数值设置监视/断点/断言(例如 (exponent > 100)
。
float_i2f()
调用时x的违规值是什么?指数是否对所有x,或某个范围都起作用?你刚才是不是说当x = 0x80800000 ?你是否对指数设置了监视,并在调试器中对该值执行步骤?应该能回答你的问题。例如,您是否检查0x807FFFFF是否有效?)
我自己用Visual Studio试过了,输入"10",看起来还行。
Q:你能给我一个"x"的输入值吗?
问:你用的是什么编译器?你在哪个平台上运行?在while循环的末尾有一行增加指数。
while((a*2) <= x)
{
if(a == 0) a =1;
if(a == 1) crash_test = exponent;
/*
if(exponent == 288)
{
exponent =0;
counter ++;
if(counter <=2)
printf("WENT OVERBOARD WTF %d ORIGINAL %d", a, crash_test);
}
*/
if(exponent > 300) break;
exponent ++;
a *= 2;
}
变量exponent
没有做任何神秘的事情。每次循环都增加exponent
,因此它最终会达到您喜欢的任何数字。真正的问题是为什么你的循环在你认为应该退出的时候没有退出?
循环条件取决于a
。尝试在循环重复时打印出a
的连续值。你注意到a
到达1073741824后发生了什么有趣的事情吗?你在课堂上听说过整数溢出吗?
只要处理"a"为负的情况(或者更好的是,验证您的输入,使其永远不会在第一个地方为负),您应该没问题:)
这里有许多无用的优化尝试,我已经删除了它们,以便代码更容易阅读。我还使用了<stdint.h>
类型作为适当的
在a *= 2
循环中存在有符号整数溢出,但主要问题是缺少常量和幻数的怪异计算。
这仍然不是典型的,因为所有的常量都应该命名,但这似乎可以可靠地工作。
#include <stdio.h>
#include <stdint.h>
uint32_t float_i2f(int32_t x) {
uint32_t sign= 0;
uint32_t exponent=0;
uint32_t fraction=0;
if (x == 0) return 0;
if ( x == 0x80000000 )
{
return 0xCF000000u;
}
if ( x < 0 )
{
sign = 0x80000000u;
x = - x;
}
else
{
sign = 0;
}
/* Count order of magnitude, this will be excessive by 1. */
for ( exponent = 1; ( 1u << exponent ) <= x; ++ exponent ) ;
if ( exponent < 24 ) {
fraction = 0x007FFFFF & ( x << 24 - exponent ); /* strip leading 1-bit */
} else {
fraction = 0x007FFFFF & ( x >> exponent - 24 );
}
exponent = (exponent + 0x7E) << 23;
return sign | exponent | fraction;
}
a
溢出。a*2==0
当a==1<<31
,所以每次exponent%32==0
, a==0
和你循环直到exponent==300
。
还有一些其他的问题:
当exponent>=24
时,fraction
计算关闭。负的左移不会自动转换为正的右移。
生成分数的掩码也有一点错误。前导位总是被假定为1
,尾数只有23位,所以x<2^23的分数应该是:
fraction = (~(((0x01)<< 31) >> 8)) & (x << (24 - (exponent + 1)));
计算exponent
的循环在abs(x)>=1<<31
时失败(如果没有适当舍入,会顺便导致精度损失);考虑隐式1
的循环在这里会更好。
- C++为什么尽管我调用了void函数,它却不起作用
- 看起来is_nothrow_constructible_v()在MSVC中被破坏了,我错了吗
- 即使我读取了所有内容,在FIFO上打开的QSocketNotifier也会一直启动
- 我写了一个C++程序来模拟Enigma机器.我没有得到输出
- 我编写了代码将十进制分数转换为其二进制等效数.它编译得很好,但在执行时挂起
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 当我输入 3 个偶数时,它表明我输入了 4
- #if 如何工作?我误解了 #if~#endif 的形式吗?
- 为什么即使我声明了朋友类,我也会收到错误"无法访问类中声明的私人成员"
- 我包含了<winuser.h>,但编译器在MonitorFromWindow上抛出"未声明"
- 我遇到了黑客排名中的问题"TWO STRINGS"的三个测试用例的分段错误。原因是什么?
- (C++)虽然循环一次不起作用,但我引入了多个变量
- 使用额外的变量使计算更容易理解 - (多少)我减慢了代码的速度?
- 我在变量上收到 3 个 C4703 错误,我认为我已经正确初始化了,但我不确定我错过了什么
- 我创建了一个将雷亚尔转换为美元的程序,但浮点变量不正确
- 为什么我的变量被重写了
- 我疯了,为什么我的变量对我变了
- 文件变得非常大,需要将数据分离到另一个文件中,但也需要使用私有变量.我怎样才能正确地做到这一点
- 我读取了一个char类型的变量,然后打印出ascii代码.为什么如果我按回车键,什么都没有
- 如果我删除了一个类,它的成员变量会自动删除吗