Я пытаюсь написать накопитель, который хорошо себя ведет, учитывая неограниченные входы. Это кажется не тривиальным и требует довольно строгого планирования. Неужели это так сложно?
int naive_accumulator(unsigned int max,
unsigned int *accumulator,
unsigned int amount) {
if(*accumulator + amount >= max) {
return 1; // could overflow
}
*accumulator += max; // could overflow
return 0;
}
int safe_accumulator(unsigned int max,
unsigned int *accumulator,
unsigned int amount) {
// if amount >= max, then certainly *accumulator + amount >= max
if(amount >= max) {
return 1;
}
// based on the comparison above, max - amount is defined
// but *accumulator + amount might not be
if(*accumulator >= max - amount) {
return 1;
}
// based on the comparison above, *accumulator + amount is defined
// and *accumulator + amount < max
*accumulator += amount;
return 0;
}
EDIT: я удалил стиль смещения
Вы считали:
if ( max - *accumulator < amount )
return 1;
*accumulator += amount;
return 0;
Изменяя направление вашего первого сравнения в "наивной" версии, вы избегаете переполнения, т.е. Видите, сколько осталось комнаты (безопасно) и сравнивайте его с суммой, которую нужно добавить (также безопасно).
Эта версия предполагает, что *accumulator
никогда не превышает max
уже при вызове функции; если вы хотите поддержать этот случай, вам придется добавить дополнительный тест.
if ( *accumulator > max ) { /* do whatever you want to do in this case */ }