Store the calculated percentage as a double rather than an int, so the granular progress bar is still granular on wide displays.

This commit is contained in:
Andrew Wood
2024-12-14 17:06:37 +00:00
parent 18c76175b2
commit f0aca0a2ce
9 changed files with 28 additions and 23 deletions
+1
View File
@@ -3,6 +3,7 @@
* *feature:* new **--bar-style** option to change the default bar style ([#15](https://codeberg.org/a-j-wood/pv/issues/15))
* *feature:* new bar formats "**%{bar-plain}**", "**%{bar-block}**", "**%{bar-granular}**", "**%{bar-shaded}**" ([#15](https://codeberg.org/a-j-wood/pv/issues/15))
* *feature:* allow decimal values such as "1.5G" with "**--size**", "**--rate-limit**", "**--buffer-size**", and "**error-skip-block**" ([#35](https://codeberg.org/a-j-wood/pv/issues/35))
* *cleanup:* track transfer percentage as a floating point value for better precision (and rounding)
* *docs:* simplified the synopsis section of the manual
### 1.9.15 - 8 December 2024
+1 -1
View File
@@ -310,7 +310,7 @@ struct pvstate_s {
off_t prev_transferred; /* total amount transferred when called last time */
int percentage; /* transfer percentage completion */
double percentage; /* transfer percentage completion */
} calc;
/********************
+2 -2
View File
@@ -86,11 +86,11 @@ extern unsigned int pv_getnum_count(const char *, bool);
extern bool pv_getnum_check(const char *, pv_numtype);
/*
* Return an integer representing the first amount as a percentage of the
* Return a value representing the first amount as a percentage of the
* second total, i.e. 100*amount/total. If the second value, the total, is
* zero or less, return 0.
*/
extern int pv_percentage(off_t, const off_t);
extern double pv_percentage(off_t, const off_t);
/*
* String handling wrappers.
+4 -4
View File
@@ -164,8 +164,8 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
}
/* Ensure the percentage is never negative or huge. */
if (state->calc.percentage < 0)
state->calc.percentage = 0;
if (state->calc.percentage > 100000)
state->calc.percentage = 100000;
if (state->calc.percentage < 0.0)
state->calc.percentage = 0.0;
if (state->calc.percentage > 100000.0)
state->calc.percentage = 100000.0;
}
+1 -1
View File
@@ -515,7 +515,7 @@ static bool pv__format_numeric(pvstate_t state, pvdisplay_t display)
msg_percent[0] = '\0';
if (show_percentage) {
(void) pv_snprintf(msg_percent, sizeof(msg_percent),
"%s%d", first_item ? "" : " ", state->calc.percentage);
"%s%.0f", first_item ? "" : " ", state->calc.percentage);
first_item = false;
}
+6 -6
View File
@@ -24,12 +24,12 @@ size_t pv_formatter_buffer_percent(pvformatter_args_t args)
return 0;
if (args->state->transfer.buffer_size > 0) {
int pct_used = pv_percentage((off_t)
(args->state->transfer.read_position -
args->state->transfer.write_position),
(off_t)
(args->state->transfer.buffer_size));
(void) pv_snprintf(content, sizeof(content), "{%3d%%}", pct_used);
double pct_used = pv_percentage((off_t)
(args->state->transfer.read_position -
args->state->transfer.write_position),
(off_t)
(args->state->transfer.buffer_size));
(void) pv_snprintf(content, sizeof(content), "{%3.0f%%}", pct_used);
}
#ifdef HAVE_SPLICE
if (args->state->transfer.splice_used)
+2 -2
View File
@@ -132,8 +132,8 @@ static size_t pv_formatter_progress_knownsize(pvformatter_args_t args, char *buf
if (has_tip && filled_bar_width > 0)
filled_bar_width -= style->tip.width;
debug("width=%d bar_area_width=%d filled_bar_width=%d after_bar_width=%d", args->segment->width, bar_area_width,
filled_bar_width, after_bar_width);
debug("percentage=%.2f width=%d bar_area_width=%d filled_bar_width=%d after_bar_width=%d", bar_percentage,
args->segment->width, bar_area_width, filled_bar_width, after_bar_width);
buffer_offset = 0;
+10 -6
View File
@@ -285,16 +285,20 @@ bool pv_getnum_check(const char *str, pv_numtype type)
/*
* Return an integer representing "amount" as a percentage of "total", i.e.
* Return a value representing "amount" as a percentage of "total", i.e.
* 100*amount/total. If "total" is zero or less, return 0.
*/
int pv_percentage(off_t amount, const off_t total)
double pv_percentage(off_t amount, const off_t total)
{
double amount_as_double;
if (total < 1)
return 0;
return 0.0;
amount *= 100;
amount /= total;
amount_as_double = (double) amount;
return (int) amount;
amount_as_double *= 100.0;
amount_as_double /= (double) total;
return amount_as_double;
}
+1 -1
View File
@@ -80,7 +80,7 @@ void pv_state_reset(pvstate_t state)
state->calc.ratesquared_sum = 0.0;
state->calc.measurements_taken = 0;
state->calc.prev_transferred = 0;
state->calc.percentage = 0;
state->calc.percentage = 0.0;
state->calc.history_first = state->calc.history_last = 0;
if (NULL != state->calc.history) {
state->calc.history[0].elapsed_sec = 0.0;