Skip to content

Commit

Permalink
findTopCellItem() handle underflow (f3)
Browse files Browse the repository at this point in the history
  • Loading branch information
Explorer09 committed Feb 6, 2024
1 parent 2480632 commit daef50d
Showing 1 changed file with 35 additions and 17 deletions.
52 changes: 35 additions & 17 deletions Meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,8 @@ static uint8_t GraphMeterMode_findTopCellItem(const Meter* this, double scaledTo
assert(topCell < graphHeight);

double valueSum = 0.0;
double maxArea = 0.0;
bool hasArea = false;
double maxValue = 0.0;
uint8_t topCellItem = this->curItems - 1;
for (uint8_t i = 0; i < this->curItems && valueSum < DBL_MAX; i++) {
double value = this->values[i];
Expand All @@ -406,26 +407,43 @@ static uint8_t GraphMeterMode_findTopCellItem(const Meter* this, double scaledTo

valueSum = newValueSum;

double topPoint = (valueSum / scaledTotal) * (double)(int)graphHeight;
double area = (value / scaledTotal) * (double)(int)graphHeight;
// Find the item that occupies the largest area of the top cell.
// Favor item with higher index in case of a tie.

if (topPoint > (double)(int)topCell || (topPoint <= 0.0 && topCell < 1)) {
// If the division underflows (topPoint <= 0.0 && topCell < 1), that
// item still counts as part of the top cell ("area" would be 0.0 in
// this case).
// if (maxValue <= 0.0)
// if (topCellItem >= i)
if (topCellItem > i) {
double topPoint = (valueSum / scaledTotal) * (double)(int)graphHeight;
assert(topPoint >= 0.0);

// Cut the excess area
if (area > topPoint - (double)(int)topCell) {
area = topPoint - (double)(int)topCell;
if (topCell > 0 && !(topPoint > (double)(int)topCell)) {
continue;
}
assert(area >= 0.0);
// If (topCell == 0), permit the cases where the division underflows
// (topPoint == 0.0).

// Find the item that occupies the largest area of the top cell.
// Favor item with higher index in case of a tie.
if (area >= maxArea) {
topCellItem = i;
maxArea = area;
}
double area = (value / scaledTotal) * (double)(int)graphHeight;
if (area > topPoint - (double)(int)topCell) {
hasArea = true;
maxValue = topPoint - (double)(int)topCell;
} else {
maxValue = value;
}
topCellItem = i;
} else {
if (hasArea) {
double area = (value / scaledTotal) * (double)(int)graphHeight;
if (area >= maxValue) {
hasArea = false;
maxValue = value;
topCellItem = i;
}
} else {
if (value >= maxValue) {
maxValue = value;
topCellItem = i;
}
}
}
}
return topCellItem;
Expand Down

0 comments on commit daef50d

Please sign in to comment.