瀏覽代碼

Increase precision for percent changes

Most notably with small percent changes, add or subtract, the error
introduced by truncation on double to integer keeps adding up.

Round raw values calculated from percentages to reduce error introduced
by truncation from double to integer.
Daniel Rodríguez 5 年之前
父節點
當前提交
ea837111b4
共有 1 個檔案被更改,包括 10 行新增6 行删除
  1. 10
    6
      src/light.c

+ 10
- 6
src/light.c 查看文件

164
 
164
 
165
 static bool _light_percent_to_raw(light_device_target_t *target, double inpercent, uint64_t *outraw)
165
 static bool _light_percent_to_raw(light_device_target_t *target, double inpercent, uint64_t *outraw)
166
 {
166
 {
167
-    uint64_t max_value = 0;
167
+    uint64_t max_value = 0, target_value;
168
+
168
     if(!target->get_max_value(target, &max_value))
169
     if(!target->get_max_value(target, &max_value))
169
     {
170
     {
170
         LIGHT_ERR("couldn't read from target");
171
         LIGHT_ERR("couldn't read from target");
171
         return false;
172
         return false;
172
     }
173
     }
173
 
174
 
174
-    double max_value_d = (double)max_value;
175
-    double target_value_d = max_value_d * (light_percent_clamp(inpercent) / 100.0);
176
-    uint64_t target_value = LIGHT_CLAMP((uint64_t)target_value_d, 0, max_value);
177
-    *outraw = target_value;
178
-    
175
+    inpercent = light_percent_clamp(inpercent);
176
+
177
+    /* Round to the nearest integer by adding 0.5 after division.
178
+       Reduces error introduced by truncation after multiple increments or
179
+       decrements. */
180
+    target_value = max_value * inpercent / 100.0 + 0.5;
181
+    *outraw = LIGHT_CLAMP(target_value, 0, max_value);
182
+
179
     return true;
183
     return true;
180
 }
184
 }
181
 
185