Hi All.
So, I have 18-bit two's complement sample data stored (sign extended) in 32-bit integers. I need to scale these numbers to fit into 16-bit integers. The obvious choice is to shift right two places. But, I want to use the two lower-order bits to round the result rather than just throwing them away. I also want the rounding to be "symmetric" for both positive and negative quotients. Meaning and answer of 8.5 would round to 9 and an answer of -8.5 would round to -9.
The code below works, but strikes me as inelegant and perhaps inefficient. Would like to hear suggestions for improving it.
Thanks.
Code:
void setup() {
int32_t sampleData[] = {37259, 37258, 37257, 37256, -37259, -37258, -37257, -37256};
int32_t sample;
int16_t scaled;
uint8_t index, bit1;
float floating;
const uint8_t sampleSize = sizeof(sampleData) / sizeof(int32_t);
Serial.println(115200);
delay(1000);
Serial.println("Division Floating Rounded");
for (index=0; index<sampleSize; index++) {
sample = sampleData[index];
floating = sample / 4.0;
Serial.print(sample); Serial.print(" / 4 "); Serial.print(floating); Serial.print(" ");
//----------- Can this code be more efficient? ------------
if (sample >=0) {
sample >>= 1;
bit1 = sample & 0b1;
sample >>= 1;
scaled = sample + bit1;
} else {
sample = -sample;
sample >>= 1;
bit1 = sample & 0b1;
sample >>= 1;
scaled = -(sample + bit1);
}
//--------------------------------------------------------
Serial.println(scaled);
}
}
void loop() {
}
Result:
Division Floating Rounded
37259 / 4 9314.75 9315
37258 / 4 9314.50 9315
37257 / 4 9314.25 9314
37256 / 4 9314.00 9314
-37259 / 4 -9314.75 -9315
-37258 / 4 -9314.50 -9315
-37257 / 4 -9314.25 -9314
-37256 / 4 -9314.00 -9314