Forum Replies Created
-
AuthorPosts
-
Robert
ParticipantYes, that would work too.
And it’s standard. And it’s a lot easier to read.
It’s pretty much the same thing.
Yes and no, but mostly no.
The intermediate 16-bit value function di() produces uses a proprietary bit layout. Besides being non-standard and harder to read code, another consequence is that standard arithmetics – like adding, subtracting, multiplying and dividing – do not work on negative numbers. Perhaps there’s still a good reason to use this proprietary format, but it must be a really good one to justify the disadvantages.Standard negative numbers use two’s complement for negative counter parts of positive integers. This is necessary to keep standard arithmetics intact and hence 0 – 1 = -1. With your proprietary format, you have two zeroes: +0 and -0. And standard arithmetics are broken: +0 – 1 = -32767 and -0 – 1 = 32767
Double: | Standard conversion (binary) | Proprietary conversion (binary)| Standard reverse | Proprietary reverse -------------+-----------------------------------------+--------------------------------+---------------------+--------------------- value = -2.00, double2fixed = -200 (0b1111111100111000), di = 32968 (0b1000000011001000), fixed2double = -2.00, id = -2.00 value = -1.90, double2fixed = -190 (0b1111111101000010), di = 32958 (0b1000000010111110), fixed2double = -1.90, id = -1.90 value = -1.80, double2fixed = -179 (0b1111111101001101), di = 32947 (0b1000000010110011), fixed2double = -1.79, id = -1.79 value = -1.70, double2fixed = -169 (0b1111111101010111), di = 32937 (0b1000000010101001), fixed2double = -1.69, id = -1.69 value = -1.60, double2fixed = -159 (0b1111111101100001), di = 32927 (0b1000000010011111), fixed2double = -1.59, id = -1.59 value = -1.50, double2fixed = -149 (0b1111111101101011), di = 32917 (0b1000000010010101), fixed2double = -1.49, id = -1.49 value = -1.40, double2fixed = -139 (0b1111111101110101), di = 32907 (0b1000000010001011), fixed2double = -1.39, id = -1.39 value = -1.30, double2fixed = -129 (0b1111111101111111), di = 32897 (0b1000000010000001), fixed2double = -1.29, id = -1.29 value = -1.20, double2fixed = -119 (0b1111111110001001), di = 32887 (0b1000000001110111), fixed2double = -1.19, id = -1.19 value = -1.10, double2fixed = -109 (0b1111111110010011), di = 32877 (0b1000000001101101), fixed2double = -1.09, id = -1.09 value = -1.00, double2fixed = -99 (0b1111111110011101), di = 32867 (0b1000000001100011), fixed2double = -0.99, id = -0.99 value = -0.90, double2fixed = -89 (0b1111111110100111), di = 32857 (0b1000000001011001), fixed2double = -0.89, id = -0.89 value = -0.80, double2fixed = -79 (0b1111111110110001), di = 32847 (0b1000000001001111), fixed2double = -0.79, id = -0.79 value = -0.70, double2fixed = -69 (0b1111111110111011), di = 32837 (0b1000000001000101), fixed2double = -0.69, id = -0.69 value = -0.60, double2fixed = -59 (0b1111111111000101), di = 32827 (0b1000000000111011), fixed2double = -0.59, id = -0.59 value = -0.50, double2fixed = -49 (0b1111111111001111), di = 32817 (0b1000000000110001), fixed2double = -0.49, id = -0.49 value = -0.40, double2fixed = -39 (0b1111111111011001), di = 32807 (0b1000000000100111), fixed2double = -0.39, id = -0.39 value = -0.30, double2fixed = -29 (0b1111111111100011), di = 32797 (0b1000000000011101), fixed2double = -0.29, id = -0.29 value = -0.20, double2fixed = -19 (0b1111111111101101), di = 32787 (0b1000000000010011), fixed2double = -0.19, id = -0.19 value = -0.10, double2fixed = -9 (0b1111111111110111), di = 32777 (0b1000000000001001), fixed2double = -0.09, id = -0.09 value = 0.00, double2fixed = 0 (0b0000000000000000), di = 0 (0b0000000000000000), fixed2double = 0.00, id = 0.00 value = 0.10, double2fixed = 10 (0b0000000000001010), di = 10 (0b0000000000001010), fixed2double = 0.10, id = 0.10 value = 0.20, double2fixed = 20 (0b0000000000010100), di = 20 (0b0000000000010100), fixed2double = 0.20, id = 0.20 value = 0.30, double2fixed = 30 (0b0000000000011110), di = 30 (0b0000000000011110), fixed2double = 0.30, id = 0.30 value = 0.40, double2fixed = 40 (0b0000000000101000), di = 40 (0b0000000000101000), fixed2double = 0.40, id = 0.40 value = 0.50, double2fixed = 50 (0b0000000000110010), di = 50 (0b0000000000110010), fixed2double = 0.50, id = 0.50 value = 0.60, double2fixed = 60 (0b0000000000111100), di = 60 (0b0000000000111100), fixed2double = 0.60, id = 0.60 value = 0.70, double2fixed = 70 (0b0000000001000110), di = 70 (0b0000000001000110), fixed2double = 0.70, id = 0.70 value = 0.80, double2fixed = 80 (0b0000000001010000), di = 80 (0b0000000001010000), fixed2double = 0.80, id = 0.80 value = 0.90, double2fixed = 90 (0b0000000001011010), di = 90 (0b0000000001011010), fixed2double = 0.90, id = 0.90 value = 1.00, double2fixed = 100 (0b0000000001100100), di = 100 (0b0000000001100100), fixed2double = 1.00, id = 1.00 value = 1.10, double2fixed = 110 (0b0000000001101110), di = 110 (0b0000000001101110), fixed2double = 1.10, id = 1.10 value = 1.20, double2fixed = 120 (0b0000000001111000), di = 120 (0b0000000001111000), fixed2double = 1.20, id = 1.20 value = 1.30, double2fixed = 130 (0b0000000010000010), di = 130 (0b0000000010000010), fixed2double = 1.30, id = 1.30 value = 1.40, double2fixed = 140 (0b0000000010001100), di = 140 (0b0000000010001100), fixed2double = 1.40, id = 1.40 value = 1.50, double2fixed = 150 (0b0000000010010110), di = 150 (0b0000000010010110), fixed2double = 1.50, id = 1.50 value = 1.60, double2fixed = 160 (0b0000000010100000), di = 160 (0b0000000010100000), fixed2double = 1.60, id = 1.60 value = 1.70, double2fixed = 170 (0b0000000010101010), di = 170 (0b0000000010101010), fixed2double = 1.70, id = 1.70 value = 1.80, double2fixed = 180 (0b0000000010110100), di = 180 (0b0000000010110100), fixed2double = 1.80, id = 1.80 value = 1.90, double2fixed = 190 (0b0000000010111110), di = 190 (0b0000000010111110), fixed2double = 1.90, id = 1.90 value = 2.00, double2fixed = 200 (0b0000000011001000), di = 200 (0b0000000011001000), fixed2double = 2.00, id = 2.00
Robert
ParticipantAs suggested per email, but to keep this top compleet: Why not using standard 16-bit signed integers?
Conversions back and forth with a little test program would look like this:
#include <stdio.h> #include <stdint.h> #define FIXED_POINT_FACTOR 100.0; int16_t double2fixed(double val) { val *= FIXED_POINT_FACTOR; if (val > INT16_MAX) return INT16_MAX; if (val < INT16_MIN) return INT16_MIN; return val; } double fixed2double(int16_t val) { return val / FIXED_POINT_FACTOR; } int main(int argc, char *argv[]) { double value; // for (value = -328.70; value < -326.01; value += 0.1) /* Test bottom edge case */ // for (value = 326.00; value < 329.01; value += 0.1) /* Test top edge case */ for (value = -2.0; value < 2.01; value += 0.1) /* Test around zero */ { int16_t converted = double2fixed(value); double back = fixed2double(converted); printf("value = %f, converted = %d, back = %f\n", value, converted, back); } }
Robert
ParticipantThank you for sharing. I’ve put the code in a little test program:
uint16_t double2int(double val) { int8_t sintp = (int8_t)val; /* signed integer part */ int8_t sdecp = (val - sintp) * 100; /* signed decimal part */ uint8_t udecp = (sdecp > 0) ? sdecp : -sdecp; /* removed decimal sign */ uint8_t uintp = sintp + 127; /* convert to unsigned */ uint16_t res = (udecp << 8) | (uint16_t)uintp; /* pack it together */ return res; } int main(int argc, char *argv[]) { double value; for (value = -2.0; value < 2.01; value += 0.1) { uint16_t converted = double2int(value); printf("value = %f, converted = %u\n", value, converted); } }
And I’m getting the following result:
value = -2.000000, converted = 125 value = -1.900000, converted = 22910 value = -1.800000, converted = 20350 value = -1.700000, converted = 17790 value = -1.600000, converted = 15230 value = -1.500000, converted = 12670 value = -1.400000, converted = 10110 value = -1.300000, converted = 7550 value = -1.200000, converted = 4990 value = -1.100000, converted = 2430 value = -1.000000, converted = 25471 value = -0.900000, converted = 22911 value = -0.800000, converted = 20351 value = -0.700000, converted = 17791 value = -0.600000, converted = 15231 value = -0.500000, converted = 12671 value = -0.400000, converted = 10111 value = -0.300000, converted = 7551 value = -0.200000, converted = 4991 value = -0.100000, converted = 2431 value = 0.000000, converted = 127 value = 0.100000, converted = 2687 value = 0.200000, converted = 5247 value = 0.300000, converted = 7807 value = 0.400000, converted = 10367 value = 0.500000, converted = 12927 value = 0.600000, converted = 15487 value = 0.700000, converted = 18047 value = 0.800000, converted = 20607 value = 0.900000, converted = 23167 value = 1.000000, converted = 128 value = 1.100000, converted = 2688 value = 1.200000, converted = 5248 value = 1.300000, converted = 7808 value = 1.400000, converted = 10368 value = 1.500000, converted = 12928 value = 1.600000, converted = 15488 value = 1.700000, converted = 18048 value = 1.800000, converted = 20608 value = 1.900000, converted = 23168 value = 2.000000, converted = 129
Though I’m not really sure what I’m looking at. Can you tell me what goes in and what’s supposed to come out? Is the output supposed to be a fixed-point value?
Robert
ParticipantThe erroneous values seem to be inversions of the actual values. When mirroring these erroneous values around the X-axis, the result seems to make sense. This sign-flipping seems to occur at temperatures just around +1°C.
Attachments:
-
AuthorPosts