In all my years of embedded programming, I've generally never needed to work with negative numbers. It's crazy, but they just don't come up very often in my line of work.
I'm currently dealing with a sensor reading that can be positive or negative and needs to be scaled by 0.006, preserving sign. To avoid needless floating point calculations during runtime, I have an algorithm that converts this to a numerator and denominator (3/500). Everything works as expected with positive numbers, but here's what happening with negatives:
Raw data: -103
Multiplied by 3: -309
Divided by 500: 36893488147419102
I figured out where that number comes from, and I have a workaround, but I'd rather trust that math is math.
Here's the same calculation in hex:
Raw data: 0xFFFFFFFFFFFFFF99
Multiplied by 3: 0xFFFFFFFFFFFFFECB
Divided by 500: 0x0083126E978D4FDE
In a calculator (SpeedCrunch):
0xFFFFFFFFFFFFFECB/500 = 0x83126E978D4FDE.9D2F1A9FBE76C8B44
That original 36893488147419102
is the integral part 0x83126E978D4FDE
of the result from SpeedCrunch.
I don't want to have to save off the sign, do a positive division, then re-add the sign back in every time I do division with negative numbers. What's going on here?
Environment is CortexM3 micro, GCC4.9.3 using c++11. The calculations are done on an int64_t
and the numerator/denominators are uint64_t
.
Edit: Here's a code snippet in response to Michael's comment below:
int64_t data = -103;
uint64_t resolutionNumerator = 3;
uint64_t resolutionDenominator = 500;
data *= resolutionNumerator;
data /= resolutionDenominator;