负数问题

时间:2013-01-20 13:51:28

标签: c pic

我有这个“简单”的代码。

union
{
    unsigned int res;
    char         bytes[2];
} ADC;

char ADC_num[5];
float temprature;

void vis_temp (void)        //  Show temp..
{ 
    signed int l, length;
    unsigned int rem;

    GO_nDONE=1;             // initiate conversion on the channel 0   

    while (GO_nDONE) continue;

    ADC.bytes[0]=ADRESL;
    ADC.bytes[1]=ADRESH;

    utoa(ADC_num, ADC.res, 10);

    temprature = (float) ADC.res * 478.1 / 1024;
    temprature = temprature - 50.0;

    l = (signed int) temprature;
    temprature -= (float) l;  
    rem = (unsigned int)(temprature* 1e1);

    sprintf(&ADC_num, "%i.%u", l, rem);

当读取温度为0度或更低的ADC_res(引脚电压,温度传感器)时,程序会写入“0.65500”而不是“-3.5”或类似值。 我应该将右边声明为signed和unsigned int。 任何修复它的提示,或者有另一种方法来修改它。

2 个答案:

答案 0 :(得分:2)

temprature = (float) ADC.res * 478.1 / 1024;
temprature = temprature - 50.0;

假设现在temprature的值为-x.yz

l = (signed int) temprature;

现在l = -x

temprature -= (float) l;

temprature = -x.yz - (-x) = -0.yz

rem = (unsigned int)(temprature* 1e1);

与10相乘,并转换为unsigned int。通常,这会导致未定义的行为(6.3.1.4(1)):

  

当实数浮动类型的有限值被转换为除_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为是未定义的。 61)

     

61)当将实数浮点类型的值转换为无符号类型时,无需执行将整数类型的值转换为无符号类型时执行的剩余操作。因此,便携式实际浮动值的范围是(−1, Utype_MAX+1)

但是将负值转换为unsigned int无论如何都会产生错误的结果,即使剩余的操作已经完成,你想要的是绝对值,所以你应该转换

rem = (unsigned int)fabsf(temprature * 1e1);

那里。

答案 1 :(得分:1)

我认为问题可能来自对utoa()功能的调用。

utoa()函数原型通常如下

char * utoa(unsigned int n, char * buffer, int radix);

在您的代码中,您已经反转了两个第一个参数。您正在通过此调用修改ADC结构。我很好奇如何在没有任何错误的情况下编译它?任何体面的编译器都会抱怨传递一个不是指针类型的参数。

尝试使用以下

utoa(ADC.res, ADC_num, 10);