开发者

C++ calculation evaluated to 0

开发者 https://www.devze.com 2022-12-29 15:53 出处:网络
I\'m parsing a file and trying to decode coordinates to the right unit. What happens is that this code is evaluated to 0. If I type it into gdb the result is correct.

I'm parsing a file and trying to decode coordinates to the right unit. What happens is that this code is evaluated to 0. If I type it into gdb the result is correct.

int pLat = (int)(
        (argv[6].data() == "plus" ? 1 : -1)
        * (     atoi(argv[7].data()) 
              + atoi(argv[8].data()) / 60. 
              + atoi(argv[9].dat开发者_如何学Goa()) / 36000.)
        * 2.145767 * 0.0001);

I'm doing a (degrees, minutes, tenth seconds) conversion to wgs. Is there something wrong with this code?


Assuming you're trying to convert degrees to WGS84 coordinates, there are two errors:

  • The conversion factor is out by a factor of 10 (180/223 is approximately 2.145767*10-5, and you have 2.145767*10-4)
  • You are multiplying by the conversion factor when you should be dividing by it. This will give you a very small number, and the cast to int will give zero.


You are casting it to int, which means you are only taking the integral part.

(int)0.7 == 0. If the expression you cast to an int is < 1, the result will be 0 due to the cast. Since 2.145767 * 0.0001 is a very small number, the chances of this happening are pretty high.

Consider using floats or doubles exclusively.

In general:

(int)x.y == x for all floats and doubles x.y. (ignoring possible overflow)


Just plugging in random values for argv[6..9] seems to produce numbers smaller than 1. When cast to int, these values will be truncated to 0. If your conversion factors are correct, you may need to use a floating-point type to represent the result.


I'll assume for now that you have defined

vector<string> argv;

and initialized it somehow.

string::data doesn't do what you seem to want. Actually, it does almost nothing. It just returns a const pointer to a version of the string, which isn't guaranteed to be null-terminated.

To compare a string to a character literal, just use ==.

To pass a string to a C function, use string::c_str.

And, you are putting a fractional number into an int.

double pLat = ( // use a floating-point type
        (argv[6] == "plus" ? 1 : -1) // compare string using ==
        * (     atoi(argv[7].c_str()) // get C string using c_str
              + atoi(argv[8].c_str()) / 60. 
              + atoi(argv[9].c_str()) / 36000.)
        * 2.145767 * 0.0001);


You are converting to int in the end which will cap all values to the smaller(!) int value. C does not round in this case.

[Edit: Sorry, my previous version of this answer contained a wrong part.]

0

精彩评论

暂无评论...
验证码 换一张
取 消