[Ovmsdev] SIM808/SIM908 GPS accuracy

Tom Saxton tom at idleloop.com
Wed Feb 8 06:50:56 HKT 2017

You're right, 1 << 7 doesn't send it off the end. That's my mistake.

00000001 << 7 is 10000000, which is -128 when treated as a signed byte and +128 when treated as unsigned. In this case, the operation should be treated as a signed int, so it should have been adding -128 (subtracting 128) instead of adding the 128 you intended. What actually happened would depend on the rest of the expression.

See for example, the casts I had to do in the function vehicle_teslaroadster_minutestocharge() to get the math to work correctly (note that bIntercept, wAvail and mx100 are all ints):

// calculate temperature to charge rate equation
bIntercept = (wAvail >= 2300) ? 288 : (signed long)745 - (signed long)199 * wAvail / 1000;
mx1000 = (signed long)3588 - (signed long)250 * wAvail / 1000;

For example, without the cast, "199 * wAvail / 1000" would get done as an int, the numerator overflows and who knows how it handles the 1000 constant. By casting 199 to a signed long, the multiply and divide both get done in longs. As I recall, the cast on 745 was required to get the subtract done as a long. It was fun getting all that code working as fast and small as possible, with no floating point and minimizing use of longs.

See also KmFromMi(), MiFromKm(), and JdToYMD() in utils.c. My favorite is JdFromYMD() which took just one cast, the "L" on 1461, to get that whole giant magic expression to evaluate correctly.


On 2/7/17, 1:22 PM, "Edward Cheeseman" <ovmsdev-bounces at lists.teslaclub.hk on behalf of cheesemanedward at gmail.com> wrote:

    I was about to complain that 128 fits into 8bits - but of course it doesn’t fit into a signed 8bit int. My bad.
    > On 8/02/2017, at 10:14 AM, Tom Saxton <tom at idleloop.com> wrote:
    > For the C18 compiler, an int is 8 bits. In C, all math is done in ints unless forced to a larger type by operands or casting. When you do (1<<7) in an 8-bit int, you shift the bit off the end of the int and get zero. The compiler didn't ignore your constant, it did exactly what it's supposed to do.
    > You can fix it with a cast, like:
    > ((long)1 << 7) or (1L << 7)
    >    Tom
    OvmsDev mailing list
    OvmsDev at lists.teslaclub.hk

More information about the OvmsDev mailing list