This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Getting odd floating point results.

((lat2-lat1)*BETA*(lat2-lat1)*BETA + (long2-long1)*delta*(long2-long1)*delta)

I'm writing some C code and I am getting some screwy results. Basically lat1, lat2, long1, long2 are all latitudes and longitudes in radians, delta is another precalculated parameter. BETA is a defined constant.

As far as I can tell this code always results in an answer equal to BETA regardless of changing inputs. Additionally when I brake out the two addition terms: (lat2-lat1)*BETA*(lat2-lat1)*BETA and (long2-long1)*delta*(long2-long1)*delta), and compute them separately I get a result of "0". I have been trying to wrap my head around what is wrong without success for a day now. Any suggestions for things to try would be appreciated.

Thanks in advance.

Parents
  • Hans-Bernhard is in fact correct...

    If you take the square root of the result of the provided code and you should get an approximate distance between two geographical coordinates.

    The intended application for this code is small distances, as a more accurate computation will not work with single precision floating point numbers.

    The issue of cancellation error strikes me as somewhat odd. I am porting code from SDCC over to keil and was getting good results while running SDCC. I'm not an expert on compilers by any means, but perhaps the C51 compiler is take some assumptions in the way that it computes results that make it more vulnerable to this type of error. Without knowing the exact differences in methods between the two compilers I can't say for sure.

    The real question then is how can I force the compiler to execute each operation in an order that minimizes the relative differences?

Reply
  • Hans-Bernhard is in fact correct...

    If you take the square root of the result of the provided code and you should get an approximate distance between two geographical coordinates.

    The intended application for this code is small distances, as a more accurate computation will not work with single precision floating point numbers.

    The issue of cancellation error strikes me as somewhat odd. I am porting code from SDCC over to keil and was getting good results while running SDCC. I'm not an expert on compilers by any means, but perhaps the C51 compiler is take some assumptions in the way that it computes results that make it more vulnerable to this type of error. Without knowing the exact differences in methods between the two compilers I can't say for sure.

    The real question then is how can I force the compiler to execute each operation in an order that minimizes the relative differences?

Children
  • Without knowing the exact differences in mehods between the two compilers I can't say for sure.

    You can't really know "the methods" as such. What you can know is what code the compilers actually generated for this task. It will take quite some guessing of what vendor library function does what, and possibly you'll have to decode intermediate results into human-readable numbers. In the end you'll probably know more than you ever really wanted to, but it can be done.

    The real question then is how can I force the compiler to execute each operation in an order that minimizes the relative differences?

    Break up the computation into individual steps. Simplify it (computing stuff twice is wasteful). Turn down optimization, optionally by using "volatile" qualifiers. Print out intermediate results for inspection.