mdview2: percent на 16-битной арифметике (убрать __divulong)
calc_md_pct/calc_raw_pct тянули 32-битное деление __divulong (+__muluint2ulong) ради показа процента в статусе. Оба дают операнды ≤16 бит (≤18432 / ≤1024), переполняет только *100. Новый pct16() масштабирует оба вниз и считает долю циклом-вычитанием — 66 Б, НОЛЬ подтянутых арифм-хелперов. Точность ±1% (на границах точно), для индикатора прокрутки незаметно. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -284,6 +284,23 @@ void fill_row(uint8_t y, uint8_t attr)
|
||||
bios_clearwin(y, 0, 1, SCREEN_W, attr);
|
||||
}
|
||||
|
||||
/* Процент 0..100 = num*100/den на чистой 16-битной арифметике — чтобы НЕ
|
||||
* тянуть 32-битное деление __divulong (~760 Б) ради показа процента в статусе.
|
||||
* Оба вызова (MD/RAW) дают операнды, влезающие в 16 бит (≤18432 и ≤1024),
|
||||
* переполняет только *100 — поэтому масштабируем оба вниз, пока num*100 не
|
||||
* влезёт в uint16, затем считаем долю циклом-вычитанием (без div-хелпера).
|
||||
* Инвариант вызовов: num ≤ den; результат всё равно ограничен 100. */
|
||||
uint8_t pct16(uint16_t num, uint16_t den)
|
||||
{
|
||||
if (den == 0) return 0;
|
||||
while (num > 655) { num >>= 1; den >>= 1; } /* num*100 ≤ 65500 < 65536 */
|
||||
if (den == 0) return 100; /* страховка от num>den */
|
||||
uint16_t n = (uint16_t)(num * 100u);
|
||||
uint8_t p = 0;
|
||||
while (n >= den && p < 100) { n = (uint16_t)(n - den); p++; }
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Отображает указанную EMM-страницу файла в окно W3.
|
||||
* Если эта страница уже активна, переключение не выполняется. */
|
||||
|
||||
Reference in New Issue
Block a user