C++ 发疯了,为什么我的变量在我身上发生变化?

C++ 发疯了,为什么我的变量在我身上发生变化?,c++,c,debugging,testing,C++,C,Debugging,Testing,好吧,我以前也遇到过这种情况,变量会因为内存分配问题或错误的寻址等而随机改变数字,比如当你使用数组越界时。但是,我没有使用数组、指针或地址,所以我不知道为什么在执行此循环后,它突然决定在循环中设置为0后的“指数”等于288: 编辑:它决定专门打开:0x80800000 这不会在一个测试中中断,我们有一个“测试”客户机,它迭代多个测试用例,每次它再次调用它,每次再次调用函数时,值应设置为等于其原始值 /* * float_i2f - Return bit-level equivalent of

好吧,我以前也遇到过这种情况,变量会因为内存分配问题或错误的寻址等而随机改变数字,比如当你使用数组越界时。但是,我没有使用数组、指针或地址,所以我不知道为什么在执行此循环后,它突然决定在循环中设置为
0
后的“指数”等于
288

编辑:它决定专门打开:
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;
}
/*
*float_i2f-表达式(float)x的返回位级等效值
*结果返回为无符号整数,但
*它将被解释为一个字节的位级表示
*单精度浮点值。
*合法运算:任何整数/无符号运算,包括| |、&&。也如果
*最多运行时间:30
*评级:4
*/
无符号浮点i2f(int x){
int符号=0;
int a=0;
int指数=0;
int crash_试验=0;
int exp=0;
整数分数=0;
int计数器=0;
如果(x==0)返回0;
如果(!(x^(0x01 31)
{

sign=0xFF使用调试器或IDE,在指数值上设置监视/断点/断言(例如
(指数>100)


调用
float_i2f()
时使用的x的值是多少?指数是针对所有x还是某个范围爆炸的


(你刚才是说当x=0x80800000时吗?你是不是在指数上设置了一个手表并在调试器中为该值步进?应该可以回答你的问题。例如,你是否检查了0x807FFFFF是否工作?)

我自己用Visual Studio试过,输入了“10”,它似乎工作正常

问:如果失败,你能给我一个输入值“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;

}

虽然((a*2)其中有许多无用的优化尝试,但我已经删除了它们,以便代码更易于阅读。此外,我还酌情使用了
类型

循环中的
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;
}
#包括
#包括
uint32浮点数i2f(int32浮点数x){
uint32\u t符号=0;
uint32_t指数=0;
uint32_t分数=0;
如果(x==0)返回0;
如果(x==0x8000000)
{
返回0xCF000000u;
}
if(x<0)
{
符号=0x80000000u;
x=-x;
}
其他的
{
符号=0;
}
/*计算数量级,这将超出1*/

对于(exponent=1;(1u变量
exponent
没有做任何神秘的事情。每次循环中,你都在增加
exponent
,因此它最终会命中你喜欢的任何数字。真正的问题是,为什么你的循环没有在你认为应该退出的时候退出


循环条件取决于
a
。在循环重复时,请尝试打印出
a
的连续值。在
a
达到1073741824后,您是否注意到有什么有趣的事情发生?您听说过类中存在整数溢出吗?

只要处理“a”为负值的情况即可(或者更好的方法是,验证您的输入,这样它就不会在第一时间变为负数),您应该很好:)
a
溢出。
a*2==0
a==1我加上
cout,这是产生错误的最小示例吗?经过288次迭代后,这正好等于…导致这一情况的x的违规值是什么?它只发生在x的一个值上吗?你知道,你只是在循环中,不断增加修正指数,最终达到288。这可能会发生得很快,因为现在循环速度很快(不再有巴贝奇时代用仓鼠来旋转齿轮的机械计算器了)。除此之外,几乎没有什么事情会突然发生。如果这是一个可重复的错误,那么你每次都在错误地做同样的事情。你需要记录或观察发生了什么,看看代码在哪里崩溃。@madmik3这正是我刚才对他说的:)需要更多信息。基本上我想说的是,是x=0x80800000当这种情况发生时,我现在试图在visual studio中测试它,我之前使用的是gdb,使用的是unix,老师为我们提供了一个测试用例程序。我相信我们使用的是gcc,我们“制造”它在unix中运行,然后在它上面执行一个测试客户机。测试客户机告诉我是否出错。它声称在测试0x80800000上它出错了,我已经把它缩小到无法前进,因为a被设置为0,而exponent被设置为288出于某种上帝预见的原因考虑查看gdb来逐步完成代码。你只需要回答一下红色你自己的问题:)“0x80800000”设置了符号位。当“a”变为负数时会发生什么?你一直乘以2?哎呀;)奇怪的格式对类是必要的,什么都没有。我不能直接使常量大于8位,也不能使用"一直在研究它,可能是它溢出了A值,似乎我必须为这种情况设置一个检查条件。不能使常数大于8位???我希望你忘记这个类教给你的东西-这段代码中有很多可怕的做法,这使得它很难验证,而且速度不比可维护的替换代码快ive。@oorosco:是的,
a
溢出,需要
未签名
。这里有一个可行的解决方案。@oorosco:永远不要忘记你的老师是一个可怜的程序员,他需要断言他的8位方法是相关的
    fraction = (~(((0x01)<< 31) >> 8)) & (x << (24 - (exponent + 1)));