Kaynağa Gözat

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 4 yıl önce
ebeveyn
işleme
ea837111b4
1 değiştirilmiş dosya ile 10 ekleme ve 6 silme
  1. 10
    6
      src/light.c

+ 10
- 6
src/light.c Dosyayı Görüntüle

@@ -164,18 +164,22 @@ static bool _light_raw_to_percent(light_device_target_t *target, uint64_t inraw,
164 164
 
165 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 169
     if(!target->get_max_value(target, &max_value))
169 170
     {
170 171
         LIGHT_ERR("couldn't read from target");
171 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 183
     return true;
180 184
 }
181 185