无直接赋值时用算术运算符复制2字节定点变量的最优方法
Alright, let's break down how to solve this efficiently—since we don't have a direct varDst = varSrc function, we need to get creative with the allowed operators. First, a quick sanity check: you mentioned a 2-byte variable, but the maximum value (2147483.647) points to a 32-bit fixed-point format (like Q24.8 or Q31.3, since 2^31-1 is 2147483647, scaled down). That’s probably a typo, but the approach below works regardless of the exact bit width—just adjust the initial step size to match your variable’s maximum value.
Core Problem & Constraints
We need to copy the value of varSrc (source) to varDst (destination) using only these operators:
add(<variable>, <constant>): Adds a constant to a variablesubtract(<variable>, <constant>): Subtracts a constant from a variablemultiply(<variable>, <constant>): Multiplies a variable by a constantdivide(<variable>, <constant>): Divides a variable by a constantcheck(<variable1>, <op>, <variable2/constant>): Compares two values (supports>,<,>=,<=,==)
The naive approach (looping add(varDst, smallest_precision) until it matches varSrc) would take millions of steps for large values—total overkill. Instead, we’ll use a binary search-style incremental method that converges in ~30 steps (log2(2147483.647 / 0.001) ≈ 31), which is exponentially faster.
Step-by-Step Optimal Implementation
You’ll need one temporary variable to track our step size (let’s call it varStep):
Initialize Variables
- Reset
varDstto 0:multiply(varDst, 0)(this works no matter what its initial value was) - Set
varStepto the maximum possible value of your variable:
(Or usemultiply(varStep, 0) add(varStep, 2147483.647)multiply(varStep, <max_constant>)if you have a pre-defined constant for the maximum value.)
- Reset
Binary Incremental Loop
Repeat these steps untilvarStepis smaller than your fixed-point format’s smallest precision (e.g., 0.001 for your max value):- Tentatively add the current step to
varDst:add(varDst, varStep) - Check if we’ve exceeded the source value:
check(varDst, >, varSrc) - If we did exceed
varSrc, undo the addition:subtract(varDst, varStep) - Halve the step size for the next iteration:
divide(varStep, 2)
- Tentatively add the current step to
Final Precision Adjustment (Optional)
After the loop, run a quickcheck(varDst, !=, varSrc)to handle any tiny precision gaps. If there’s a mismatch, add/subtract the smallest precision constant (e.g., 0.001) tovarDstuntil it matches.
Why This Is the Best Approach
- Minimal operations: We only need ~30 iterations to cover the entire value range, compared to millions for a linear loop.
- Universal compatibility: Works for any value of
varSrc(0, max, or anything in between) and converges to the exact fixed-point representation. - Stays within constraints: Every step uses only the operators you listed—no workarounds outside your toolset.
Quick Example Walkthrough
Let’s say varSrc = 10.0:
- Start with
varDst = 0,varStep = 2147483.647 - Add step to
varDst(now 2147483.647), check if >10 → yes, subtract back to 0. Halve step to ~1073741.823 - Repeat until
varStepbecomes 8.0: add tovarDst(now 8.0), check <=10 → yes, keep it. Halve step to 4.0 - Add 4.0 →
varDst=12.0, check >10 → yes, subtract back to 8.0. Halve step to 2.0 - Add 2.0 →
varDst=10.0, check <=10 → yes, keep it. Halve step and continue until step is smaller than 0.001. Done!
内容的提问来源于stack exchange,提问作者Thomas Boby

