gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ✘gpsd .23.2~rc1


From: Fred Wright
Subject: Re: ✘gpsd .23.2~rc1
Date: Thu, 14 Apr 2022 20:26:06 -0700 (PDT)


On Thu, 14 Apr 2022, Gary E. Miller wrote:
On Thu, 14 Apr 2022 15:11:54 -0700 (PDT)
Fred Wright <fw@fwright.net> wrote:

On Wed, 13 Apr 2022, Gary E. Miller wrote:

That log is your HPPOSLLH issue.  I have a working fix for that
too, but not tonight.

Thatt collides with what I was doing, as well as being slightly
wrong, and now I have to do more work to sort it out.

At least it works.

The general concept is the same as my change, i.e. combining the two
pieces as integers before a single conversion to FP.  But:

Good.

1) You're defining the multiplier as 100L, when it should be 100LL.
With 100L on a 32-bit platform, it will compute the combined integer
in 32 bits and potentially overflow it.

which is why the (int64_t) to ensure 64 bit math.

That was only there in the ECEF cases, which is why I hadn't noticed it.

100LL forces 64 bits in all
cases, which is guaranteed to accommodate any value the receiver can
report.  It's of course a don't-care on 64-bit platforms.

Same-o, same-o.  Standard C promotes to the largest integer in the
equation.

Yup.  And writing the constant as 100LL is the most concise way.

2) I'm not sure whether casting the constant to double actually
matters in this context, but it certainly doesn't hurt, so it might
as well be there.

My tests show it is required.  To keep C from using (long double)
math when  FLT_EVAL_MATCH != 0.

3) Changing the scaling from multiplication to division simply slows
it down without improving the accuracy.

Yes, and no.  "/ 100" is exact, until the divide is done.  "* 1e-2",
the old way is a problem since a double, long double sane not store
it exactly.  Since some C comciplers store is as a (double) and
others as a (long double), that wass one source of the problems.

THis test case, that I posted earlier, shows the problem:

   #include <float.h>
   #include <stdio.h>

   int r1;
   double ten = 10.0;

   int main(int c, char **v)
   {
       r1 = 0.1 == (1.0 / ten);
       printf("FLT_EVAL_METHOD %d\n", FLT_EVAL_METHOD);
       printf("1=%d\n",  r1);
   }

The problem is floating point constants at compile time!

It's tempting to think that
the division approach is more accurate since the constant can be
represented exactly,

Not worried about "accuracy", worried about portability.  I changed it
because it broke portability.

but ultimately there needs to be a division by a
power of 10 at some point either way, with the only difference being
whether it does that at compile time in computing the constant, or at
run time.

Yup.  And the compile time randomness was one of the portability
problems.

The latter is more expensive, and not likely to be more
accurate unless the compiler is screwing up computing the constant in
the former case.

Not worried about "accuracy", worried about portability.  I changed it
because it broke portability.

Empirically, your version changed several values in the .chk file. I didn't go through them all, but the one I looked at looked like it was a slightly worse result. It's all very nitpicking except for the tests, since it's about rounding a value that's nominally exactly halfway between two allowable values in the JSON precision, which is less than the uBlox precision.

The whole JSON precision issue needs looking into, but not right now. For example, uBlox NAV-PVT reports altitudes with millimeter precision, and NAV_HPPOSLLH provides 10-micron precision. The JSON has 100-micron precision, so it's overkill in the standard case and deficient in the high-precision case. Not that it's very likely to matter in real use cases, since a receiver is hard pressed even to deliver millimeter accuracy on a single real-time fix, especially in the vertical dimension.

Also, in spite of your attempts to control FLT_EVAL_METHOD, the FLT_VOLATILE hack is still needed. Taking it out caused about a dozen errors on nmea-fuzzy-cases in 32-bit OpenBSD, so I put it back. It's a complete NOP any time FLT_EVAL_METHOD < 2, anyway.

My version now passes all tests on the 22 platforms I tested, which wasn't true of yours.

Fred Wright



reply via email to

[Prev in Thread] Current Thread [Next in Thread]