在 C 中转换为 float 时得到奇怪的值

问题描述 投票:0回答:1

我在

TI C654X_0 MCU
中运行下面的代码,但总是得到日志中给出的
xval, yval, zval -> f, f, f
的奇怪结果。我在在线C编译器中运行相同的代码,结果是正确的。我不明白为什么会出现这个问题。

#include <stdio.h>
#include <math.h>
#define PI 3.141592654

....
obj.x = 14690; obj.y = 14347; obj.z = 14607;

uint32_t patternCheck(detectedObj obj)
{
   uint32_t retVal = 0;
   int xyzQFormat = 7;

   if(obj.x != 0 && obj.y !=0 && obj.z!=0){   
    float xval = (float)abs(obj.x) / (1 << xyzQFormat);
    float yval = (float)abs(obj.y) / (1 << xyzQFormat);
    float zval = (float)abs(obj.z) / (1 << xyzQFormat);
    float objAdeg = (atan(xval / yval) * 180) / PI;
    float objEdeg = (atan(zval / yval) * 180) / PI;
    float objAdist = sqrt(xval*xval + yval*yval);
    float objEdist = sqrt(zval*zval + yval*yval);
    System_printf("%d, %d, %d, %2.6f, %2.6f, %2.6f, %d \n", obj.x, obj.y, obj.z, xval, yval, zval, xyzQFormat);
    retVal = 1;
   }

   return retVal;
}

日志:

[C674X_0] 14690, 14347, 14607,  f,  f,  f, 7 
c
1个回答
1
投票

这是一个可能的“解决方法”(阅读:“kludge”),您可以通过它来规避问题。您可以尝试使用自己的浮点到字符串转换来“绕过”明显有障碍的

System_printf()

#include <stdio.h>
#include <math.h>

char *myFPfmt( char *dst, double val ) {
    int wh = floor( val );
    // Simplistic rounding and integer conversion
    int fr = floor( (val-wh)*1000*1000 + 0.5 );

    sprintf( dst, "%d.%06d", wh, fr ); // Can you get "leading 0s" at least?

    return dst;
}

int main( void ) {
    double pi =  3.141592654;
    double eu =  2.718281828459;
    double da = 42.0042069;

    char buf[3][16]; // 3 values -> 3 buffers

    printf( "%2.6f  %2.6f  %2.6f\n", pi, eu, da );
    printf( "%s  %s  %s\n", myFPfmt( buf[0], pi ), myFPfmt( buf[1], eu ), myFPfmt( buf[2], da ) );

    return 0;
}

输出

3.141593  2.718282  42.004207
3.141593  2.718282  42.004207

了解了基础知识(我们希望),承认数字可以小于零:

char *myFPfmt( char *dst, double val ) {
    char *sgn = val >= 0.0 ? "" : "-";
    val = fabs(val);
    int wh = floor( val );
    // Simplistic rounding and integer conversion
    int fr = floor( (val-wh)*1000*1000 + 0.5 );

    sprintf( dst, "%s%d.%06d", sgn, wh, fr ); // Can you get "leading 0s" at least?

    return dst;
}

还有一个测试:

// test results of converting a single negative value
printf( "%s\n", myFPfmt( buf[0], (double)-13.0000789 ) );

单次测试输出

-13.000079

注意:对于只有五位精度的数据,六位精度是不合理的。

© www.soinside.com 2019 - 2024. All rights reserved.