Skip to content

Commit 52baa26

Browse files
FintasticManmark9064
authored andcommitted
weather: Fix incorrect rounding for negative temperatures
1 parent 66b5977 commit 52baa26

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

src/components/ble/SimpleWeatherService.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "components/datetime/DateTimeController.h"
3535
#include <lvgl/lvgl.h>
3636
#include "displayapp/InfiniTimeTheme.h"
37+
#include "utility/Math.h"
3738

3839
int WeatherCallback(uint16_t connHandle, uint16_t attrHandle, struct ble_gatt_access_ctxt* ctxt, void* arg);
3940

@@ -77,11 +78,11 @@ namespace Pinetime {
7778
}
7879

7980
[[nodiscard]] int16_t Celsius() const {
80-
return (PreciseCelsius() + 50) / 100;
81+
return Utility::RoundedDiv(PreciseCelsius(), static_cast<int16_t>(100));
8182
}
8283

8384
[[nodiscard]] int16_t Fahrenheit() const {
84-
return (PreciseFahrenheit() + 50) / 100;
85+
return Utility::RoundedDiv(PreciseFahrenheit(), static_cast<int16_t>(100));
8586
}
8687

8788
[[nodiscard]] lv_color_t Color() const {

src/utility/Math.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
11
#pragma once
22

33
#include <cstdint>
4+
#include <concepts>
45

56
namespace Pinetime {
67
namespace Utility {
78
// returns the arcsin of `arg`. asin(-32767) = -90, asin(32767) = 90
89
int16_t Asin(int16_t arg);
10+
11+
// Round half away from zero integer division
12+
// If T signed, divisor cannot be std::numeric_limits<T>::min()
13+
// Adapted from https://github.com/lucianpls/rounding_integer_division
14+
// Under the MIT license
15+
template <std::integral T>
16+
constexpr T RoundedDiv(T dividend, T divisor) {
17+
bool neg = divisor < 0;
18+
if (neg) {
19+
// overflows if divisor is minimum value for T
20+
divisor = -divisor;
21+
}
22+
23+
T m = dividend % divisor;
24+
T h = divisor / 2 + divisor % 2;
25+
T res = (dividend / divisor) + (!(dividend < 0) & (m >= h)) - ((dividend < 0) & ((m + h) <= 0));
26+
27+
if (neg) {
28+
res = -res;
29+
}
30+
return res;
31+
}
932
}
1033
}

0 commit comments

Comments
 (0)