mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Do pressure-time integral using integer values
Now that the pressure_time calculations are done in our "native" integer units (millibar and seconds), we might as well keep using integer variables. We still do floating point calculations at various stages for the conversions (including turning a depth in mm into a pressure in mbar), so it's not like this avoids floating point per se. And the final approximation is still done as a fraction of the pressure-time values, using floating point. So floating point is very much involved, but it's used for conversions, not (for example) to sum up lots of small values. With floating point, I had to think about the dynamic range in order to convince myself that summing up small values will not subtly lose precision. With integers, those kinds of issues do not exist. The "lost precision" case is not subtle, it would be a very obvious overflow, and it's easy to think about. It turns out that for the pressure-time integral to overflow in "just" 31 bits, we'd have to have pressures and times that aren't even close to the range of scuba cylinder air use (eg "spend more than a day at a depth of 200+ m"). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
1ee0101b28
commit
d281ad84fd
1 changed files with 7 additions and 7 deletions
14
profile.c
14
profile.c
|
@ -1264,7 +1264,7 @@ struct pr_track_struct {
|
|||
int end;
|
||||
int t_start;
|
||||
int t_end;
|
||||
double pressure_time;
|
||||
int pressure_time;
|
||||
pr_track_t *next;
|
||||
};
|
||||
|
||||
|
@ -1274,7 +1274,7 @@ static pr_track_t *pr_track_alloc(int start, int t_start) {
|
|||
pt->t_start = t_start;
|
||||
pt->end = 0;
|
||||
pt->t_end = 0;
|
||||
pt->pressure_time = 0.0;
|
||||
pt->pressure_time = 0;
|
||||
pt->next = NULL;
|
||||
return pt;
|
||||
}
|
||||
|
@ -1316,7 +1316,7 @@ static void dump_pr_track(pr_track_t **track_pr)
|
|||
for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
|
||||
list = track_pr[cyl];
|
||||
while (list) {
|
||||
printf("cyl%d: start %d end %d t_start %d t_end %d pt %6.3f\n", cyl,
|
||||
printf("cyl%d: start %d end %d t_start %d t_end %d pt %d\n", cyl,
|
||||
list->start, list->end, list->t_start, list->t_end, list->pressure_time);
|
||||
list = list->next;
|
||||
}
|
||||
|
@ -1346,7 +1346,7 @@ static void fill_missing_segment_pressures(pr_track_t *list)
|
|||
while (list) {
|
||||
int start = list->start, end;
|
||||
pr_track_t *tmp = list;
|
||||
double pt_sum = 0.0, pt = 0.0;
|
||||
int pt_sum = 0, pt = 0;
|
||||
|
||||
for (;;) {
|
||||
pt_sum += tmp->pressure_time;
|
||||
|
@ -1377,7 +1377,7 @@ static void fill_missing_segment_pressures(pr_track_t *list)
|
|||
pt += list->pressure_time;
|
||||
pressure = start;
|
||||
if (pt_sum)
|
||||
pressure -= (start-end)*pt/pt_sum;
|
||||
pressure -= (start-end)*(double)pt/pt_sum;
|
||||
list->end = pressure;
|
||||
if (list == tmp)
|
||||
break;
|
||||
|
@ -1401,7 +1401,7 @@ static void fill_missing_segment_pressures(pr_track_t *list)
|
|||
* scale pressures, so it ends up being a unitless scaling
|
||||
* factor.
|
||||
*/
|
||||
static inline double pressure_time(struct dive *dive, struct plot_data *a, struct plot_data *b)
|
||||
static inline int pressure_time(struct dive *dive, struct plot_data *a, struct plot_data *b)
|
||||
{
|
||||
int time = b->sec - a->sec;
|
||||
int depth = (a->depth + b->depth)/2;
|
||||
|
@ -1451,7 +1451,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
|
|||
}
|
||||
|
||||
/* Overall pressure change over total pressure-time for this segment*/
|
||||
magic = (segment->end - segment->start) / segment->pressure_time;
|
||||
magic = (segment->end - segment->start) / (double) segment->pressure_time;
|
||||
|
||||
/* Use that overall pressure change to update the current pressure */
|
||||
cur_pt = pressure_time(dive, entry-1, entry);
|
||||
|
|
Loading…
Reference in a new issue