Fixed-point arithmetic helps embedded devices do math fast using limited memory. It is useful when floating-point is too slow or unavailable.
Fixed-point arithmetic for embedded DSP in Signal Processing
Qm.n format: number has m bits for integer part and n bits for fractional part. Example: Q1.15 means 1 bit integer, 15 bits fraction.
Fixed-point numbers are stored as integers but represent fractions.
Scaling and shifting bits are used to do multiplication and division.
Q1.15 format stores numbers like 0.5 as 16384 (because 0.5 * 2^15 = 16384).
To multiply two Q1.15 numbers: multiply integers, then shift right by 15 bits to keep scale.
Adding two Q1.15 numbers is just integer addition.
This code multiplies two fixed-point numbers in Q1.15 format and converts the result back to float to check correctness.
def fixed_point_multiply(a, b, fractional_bits=15): product = a * b # Shift right to keep scale result = product >> fractional_bits return result # Example: multiply 0.5 * 0.25 in Q1.15 # 0.5 in Q1.15 is int(0.5 * 2**15) = 16384 # 0.25 in Q1.15 is int(0.25 * 2**15) = 8192 a = 16384 b = 8192 result = fixed_point_multiply(a, b) # Convert back to float for display float_result = result / (2**15) print(f"Fixed-point multiply result (int): {result}") print(f"Fixed-point multiply result (float): {float_result}")
Be careful with overflow: fixed-point math can overflow if numbers get too big.
Always keep track of the number of fractional bits to interpret results correctly.
Fixed-point math is faster but less flexible than floating-point.
Fixed-point arithmetic stores fractions as scaled integers for fast math on small devices.
Multiplication requires shifting bits to keep the scale correct.
Use fixed-point when floating-point hardware is not available or too slow.
Practice
Solution
Step 1: Understand fixed-point arithmetic purpose
Fixed-point arithmetic is used to perform calculations efficiently on devices that lack floating-point hardware.Step 2: Compare options with this purpose
To perform fast math on devices without floating-point hardware correctly states the main reason: fast math on devices without floating-point units. Other options are incorrect because fixed-point does not increase precision beyond floating-point, does not simplify programming by avoiding scaling, and does not use more memory.Final Answer:
To perform fast math on devices without floating-point hardware -> Option BQuick Check:
Fixed-point speeds math on limited hardware = A [OK]
- Thinking fixed-point increases precision beyond floating-point
- Assuming fixed-point uses more memory
- Believing fixed-point avoids scaling complexity
Solution
Step 1: Understand fixed-point scaling
For 8 fractional bits, multiply the integer value by 2^8 (which is shifting left by 8) to convert to fixed-point.Step 2: Match with options
int16_t fixed = value << 8; shifts left by 8 bits, correctly scaling the value. int16_t fixed = value >> 8; shifts right (wrong direction), A divides by 8 (wrong), C multiplies by 8 (not 256).Final Answer:
int16_t fixed = value << 8; -> Option AQuick Check:
Shift left by fractional bits to scale = D [OK]
- Shifting right instead of left
- Multiplying/dividing by wrong powers of two
- Confusing fractional bits with decimal places
a = 0x0100 (1.0) and b = 0x0200 (2.0), what is the fixed-point result of c = (a * b) >> 8;?Solution
Step 1: Multiply fixed-point values
a * b = 0x0100 * 0x0200 = 256 * 512 = 131072 (decimal)Step 2: Adjust scale by shifting right 8 bits
c = 131072 >> 8 = 131072 / 256 = 512 decimal = 0x0200Step 3: Recalculate carefully
Wait, 0x0100 = 256 decimal, 0x0200 = 512 decimal. Multiplying: 256 * 512 = 131072 decimal. Shifting right 8 bits divides by 256: 131072 / 256 = 512 decimal = 0x0200. So c = 0x0200 (2.0).Final Answer:
0x0200 (2.0) -> Option CQuick Check:
(1.0 * 2.0) = 2.0 fixed-point = 0x0200 [OK]
- Forgetting to shift right after multiplication
- Misinterpreting hex values as decimal
- Incorrect bit shift amount
int16_t a = 0x0100; // 1.0 int16_t b = 0x0200; // 2.0 int16_t c = a * b;
Solution
Step 1: Understand fixed-point multiplication scaling
Multiplying two fixed-point numbers doubles the fractional bits, so the result must be shifted right by the fractional bit count to rescale.Step 2: Analyze given code
The code multiplies a and b but does not shift right by 8 bits, so the scale is incorrect.Final Answer:
Missing right shift to rescale after multiplication -> Option AQuick Check:
Shift right after multiply to fix scale = C [OK]
- Not shifting right after multiplication
- Using float instead of fixed-point on embedded
- Shifting left instead of right
Solution
Step 1: Understand fixed-point multiplication with 12 fractional bits
Multiplying two fixed-point numbers doubles fractional bits (24 bits), so shifting right by 12 bits rescales back to 12 fractional bits.Step 2: Prevent overflow by using wider integer
Multiplying two 16-bit numbers can overflow 16 bits, so use a 32-bit integer to hold the intermediate product safely.Final Answer:
Multiply, then shift right by 12 bits, and store in a 32-bit integer -> Option DQuick Check:
Shift right after multiply and use wider int = B [OK]
- Not using wider integer causing overflow
- Shifting left instead of right after multiply
- Shifting before multiply losing precision
Ready to prove it?
Pass the test and this pattern moves unknown
