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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user