Skip to content

Commit 0ee2969

Browse files
refactor: improve float writing logic for precision handling in MeadeResponse
1 parent eb154fa commit 0ee2969

2 files changed

Lines changed: 69 additions & 41 deletions

File tree

src/core/meade/MeadeParserExtra.cpp

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,89 +23,89 @@ namespace meade
2323
namespace
2424
{
2525

26-
MeadeResponse handleExtraGetLeaf(MeadeResponse &r, const char *leafInput, IMeadeExtraHandlers &h)
26+
void handleExtraGetLeaf(MeadeResponse &r, const char *leafInput, IMeadeExtraHandlers &h)
2727
{
2828
if (leafInput == nullptr || leafInput[0] == '\0')
2929
{
30-
return r;
30+
return;
3131
}
3232

3333
if (isExact(leafInput, "R"))
3434
{
3535
fillNumericFloatResponse(r, h.onGetRaStepsPerDegree(), 1);
36-
return r;
36+
return;
3737
}
3838
if (isExact(leafInput, "D"))
3939
{
4040
fillNumericFloatResponse(r, h.onGetDecStepsPerDegree(), 1);
41-
return r;
41+
return;
4242
}
4343
if (isExact(leafInput, "DL"))
4444
{
4545
ExtraDecLimits lim = h.onGetDecLimits();
4646
fillDecLimitsPairResponse(r, lim.lo, lim.hi);
47-
return r;
47+
return;
4848
}
4949
if (isExact(leafInput, "DLL"))
5050
{
5151
fillNumericFloatResponse(r, h.onGetDecLimits().lo, 1);
52-
return r;
52+
return;
5353
}
5454
if (isExact(leafInput, "DLU"))
5555
{
5656
fillNumericFloatResponse(r, h.onGetDecLimits().hi, 1);
57-
return r;
57+
return;
5858
}
5959
if (startsWith(leafInput, "DL"))
6060
{
6161
fillBooleanResponse(r, false);
62-
return r;
62+
return;
6363
}
6464
if (isExact(leafInput, "DP"))
6565
{
6666
fillBooleanResponse(r, false);
67-
return r;
67+
return;
6868
}
6969
if (isExact(leafInput, "S"))
7070
{
7171
fillNumericFloatResponse(r, h.onGetTrackingSpeedCalibration(), 5);
72-
return r;
72+
return;
7373
}
7474
if (isExact(leafInput, "ST"))
7575
{
7676
fillNumericFloatResponse(r, h.onGetRemainingSafeTime(), 7);
77-
return r;
77+
return;
7878
}
7979
if (isExact(leafInput, "T"))
8080
{
8181
fillNumericFloatResponse(r, h.onGetTrackingSpeed(), 7);
82-
return r;
82+
return;
8383
}
8484
if (isExact(leafInput, "B"))
8585
{
8686
fillIntResponse(r, h.onGetBacklashSteps());
87-
return r;
87+
return;
8888
}
8989
if (isExact(leafInput, "A"))
9090
{
9191
fillNumericFloatResponse(r, h.onGetAltStepsPerDegree(), 1);
92-
return r;
92+
return;
9393
}
9494
if (isExact(leafInput, "AH"))
9595
{
9696
fillFramedTextResponse(r, h.onGetAutoHomingStates());
97-
return r;
97+
return;
9898
}
9999
if (isExact(leafInput, "AA"))
100100
{
101101
ExtraAzAltPositions p = h.onGetAzAltPositions();
102102
fillLongPairPipeResponse(r, p.az, p.alt);
103-
return r;
103+
return;
104104
}
105105
if (isExact(leafInput, "Z"))
106106
{
107107
fillNumericFloatResponse(r, h.onGetAzStepsPerDegree(), 1);
108-
return r;
108+
return;
109109
}
110110
if (startsWith(leafInput, "C"))
111111
{
@@ -114,67 +114,69 @@ MeadeResponse handleExtraGetLeaf(MeadeResponse &r, const char *leafInput, IMeade
114114
const char *star = strchr(payload, '*');
115115
if (star == nullptr || star == payload)
116116
{
117-
return r;
117+
return;
118118
}
119119
const float raCoord = static_cast<float>(strtod(payload, nullptr));
120120
const float decCoord = static_cast<float>(strtod(star + 1, nullptr));
121121
ExtraStepperCoords pos = h.onGetTargetCoordinatePositions(raCoord, decCoord);
122122
fillLongPairPipeResponse(r, pos.raPos, pos.decPos);
123-
return r;
123+
return;
124124
}
125125
if (isExact(leafInput, "MS"))
126126
{
127127
fillFramedTextResponse(r, h.onGetStepperInfo());
128-
return r;
128+
return;
129129
}
130130
if (startsWith(leafInput, "M"))
131131
{
132132
fillFramedTextResponse(r, h.onGetMountHardwareInfo());
133-
return r;
133+
return;
134134
}
135135
if (isExact(leafInput, "O"))
136136
{
137137
fillLiteralResponse(r, h.onGetLogBuffer());
138-
return r;
138+
return;
139139
}
140+
// H-family keys: order matters — exact matches ("HR", "HD", "HS", "H")
141+
// must precede startsWith("H") which acts as catch-all for unknown H- keys.
140142
if (isExact(leafInput, "HR"))
141143
{
142144
fillLongResponse(r, h.onGetRaHomingOffset());
143-
return r;
145+
return;
144146
}
145147
if (isExact(leafInput, "HD"))
146148
{
147149
fillLongResponse(r, h.onGetDecHomingOffset());
148-
return r;
150+
return;
149151
}
150152
if (isExact(leafInput, "HS"))
151153
{
152154
fillHemisphereResponse(r, h.onGetHemisphere());
153-
return r;
155+
return;
154156
}
155157
if (isExact(leafInput, "H"))
156158
{
157159
ExtraHms t = h.onGetHourAngle();
158160
fillCompactHmsResponse(r, t.hours, t.minutes, t.seconds);
159-
return r;
161+
return;
160162
}
161163
if (startsWith(leafInput, "H"))
162164
{
163165
fillBooleanResponse(r, false);
164-
return r;
166+
return;
165167
}
166168
if (isExact(leafInput, "L"))
167169
{
168170
ExtraHms t = h.onGetLocalSiderealTime();
169171
fillCompactHmsResponse(r, t.hours, t.minutes, t.seconds);
170-
return r;
172+
return;
171173
}
172174
if (isExact(leafInput, "N"))
173175
{
174176
fillFramedTextResponse(r, h.onGetNetworkStatus());
175-
return r;
177+
return;
176178
}
177-
return r;
179+
return;
178180
}
179181

180182
void handleExtraSetLeaf(MeadeResponse &r, const char *leafInput, IMeadeExtraHandlers &h)

src/core/meade/MeadeParserHelpers.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -418,29 +418,55 @@ void writeFloat(MeadeResponse &r, float value, int precision)
418418
v = -v;
419419
}
420420

421-
// Separate integer and fractional parts.
422-
int intVal = static_cast<int>(v);
423-
double frac = v - static_cast<double>(intVal);
421+
// Round the entire value to the target precision, then extract integer
422+
// and fractional digits from the rounded integer. This avoids the
423+
// streaming frac *= 10.0 loop whose floating-point rounding could
424+
// produce a spurious digit 10.
425+
double scale = 1.0;
426+
for (int i = 0; i < precision; ++i)
427+
{
428+
scale *= 10.0;
429+
}
430+
long total = static_cast<long>(v * scale + 0.5);
431+
long intPart = total / static_cast<long>(scale);
432+
long fracPart = total % static_cast<long>(scale);
424433

425434
if (negative)
426435
{
427436
writeChar(r, '-');
428437
}
429-
writeInt(r, intVal);
430438

439+
// Integer part.
440+
if (intPart == 0)
441+
{
442+
writeChar(r, '0');
443+
}
444+
else
445+
{
446+
char buf[22];
447+
int n = 0;
448+
while (intPart > 0 && n < 20)
449+
{
450+
buf[n++] = static_cast<char>('0' + (intPart % 10));
451+
intPart /= 10;
452+
}
453+
while (n > 0)
454+
{
455+
writeChar(r, buf[--n]);
456+
}
457+
}
458+
459+
// Fractional part (MSD first).
431460
if (precision > 0)
432461
{
433462
writeChar(r, '.');
463+
long divisor = static_cast<long>(scale) / 10;
434464
for (int i = 0; i < precision; ++i)
435465
{
436-
frac *= 10.0;
437-
int digit = static_cast<int>(frac);
438-
if (digit > 9)
439-
{
440-
digit = 9; // guard against floating-point rounding
441-
}
466+
int digit = static_cast<int>(fracPart / divisor);
442467
writeUnsignedPadded(r, static_cast<unsigned>(digit), 1);
443-
frac -= static_cast<double>(digit);
468+
fracPart %= divisor;
469+
divisor /= 10;
444470
}
445471
}
446472
}

0 commit comments

Comments
 (0)