<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing?]]></title><description><![CDATA[<blockquote>
<p dir="auto">[!WARNING]<br />
<strong>Technical Redaction &amp; Safe Harbor Notice</strong>:<br />
All communication captures, system titles, and cryptographic parameters in this thread have been sanitized and neutralized. Real utility meter identifiers, production encryption keys (GUEK/GAK/MK), SIM IMSIs, and proprietary network envelopes have been substituted with standard IEC 62056 synthetic test vectors. Do not post unredacted production captures or live cryptographic keys.</p>
</blockquote>
<p dir="auto">We are auditing smart meter billing integration between DLMS/COSEM meters and Head-End MDM systems. When reading instantaneous current (OBIS <code>1.0.31.7.0.255</code>, L1 Current, Class 3) and accumulated active import energy (OBIS <code>1.0.1.8.0.255</code>, Total Energy, Class 3), we discovered two severe data corruption anomalies across several client parsers:</p>
<ol>
<li><strong>The $10^{253}$ Value Explosion</strong>: For Current L1 (raw value = 5230 mA, expected = 5.230 A), some parsing libraries reported <code>5.23e+256</code> A!</li>
<li><strong>Billing Drift on High Energy Meters</strong>: For industrial meters with cumulative energy &gt; 167,772.16 kWh (raw value = <code>0x000100000001</code> Wh), converting the integer to standard <code>float32</code> resulted in lost energy increments and billing discrepancies!</li>
</ol>
<p dir="auto">Here is the raw <code>Get-Response-Normal</code> for Current L1 (<code>1.0.31.7.0.255</code> Attribute 2 &amp; 3):</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 10 C4 01 C1 00 02 02 12 14 6E 02 02 0F FD 16 21
</code></pre>
<p dir="auto">Dissecting the structure:</p>
<ul>
<li><code>12 14 6E</code>: Long-Unsigned <code>5230</code></li>
<li><code>02 02</code>: Structure of 2 elements (<code>scaler_unit</code>)</li>
<li><code>0F FD</code>: <code>scaler</code> (Integer8)</li>
<li><code>16 21</code>: <code>unit</code> (Enum 33 = Ampere [A])</li>
</ul>
<p dir="auto">Why did the scaler byte <code>0xFD</code> cause a $10^{253}$ explosion?</p>
]]></description><link>https://dlms.sharur.org/topic/61/why-does-signed-8-bit-negative-scaler-3-cause-10-253-overflow-and-float32-rounding-errors-in-smart-metering-billing</link><generator>RSS for Node</generator><lastBuildDate>Fri, 16 Oct 2026 19:14:35 GMT</lastBuildDate><atom:link href="https://dlms.sharur.org/topic/61.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 22 Aug 2026 17:22:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:52 GMT]]></title><description><![CDATA[<p dir="auto">To synthesize for the community, here is the robust, production-grade Python decoder:</p>
<pre><code class="language-python">from decimal import Decimal
import struct

def decode_dlms_register(raw_val_int, scaler_byte, unit_enum):
    # 1. Decode Scaler as Signed 8-bit Integer
    scaler = struct.unpack('b', bytes([scaler_byte]))[0]
    
    # 2. Use Decimal Arithmetic to prevent Float32 precision loss
    raw_dec = Decimal(str(raw_val_int))
    scale_factor = Decimal(10) ** Decimal(scaler)
    physical_value = raw_dec * scale_factor
    
    print(f"[+] Scaler: {scaler}, Scale Factor: 10^{scaler}")
    print(f"[+] Exact Physical Value: {physical_value} (Unit Enum: {unit_enum})")
    return physical_value

# Test Case 1: L1 Current (5230 mA, Scaler 0xFD = -3)
assert decode_dlms_register(5230, 0xFD, 33) == Decimal("5.230")

# Test Case 2: Cumulative Energy (20,000,000 Wh, Scaler 0x00 = 0)
assert decode_dlms_register(20000000, 0x00, 30) == Decimal("20000000")
</code></pre>
<h3>Summary Checklist for Register Parsing:</h3>
<ol>
<li><strong>Signed Scaler</strong>: Always unpack Tag <code>0x0F</code> as signed 8-bit integer (<code>struct.unpack('b')</code>).</li>
<li><strong>Decimal Arithmetic</strong>: Use <code>Decimal</code> or <code>float64</code> to prevent mantissa truncation on high cumulative energy registers (Blue Book Section 4.3.3).</li>
<li><strong>Unit Mapping</strong>: Map unit enums to standard SI physical dimensions.</li>
</ol>
]]></description><link>https://dlms.sharur.org/post/229</link><guid isPermaLink="true">https://dlms.sharur.org/post/229</guid><dc:creator><![CDATA[sarah_jenkins]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:52 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:47 GMT]]></title><description><![CDATA[<p dir="auto">Here is the verified A-XDR payload for Active Energy Import (<code>1.0.1.8.0.255</code><img src="https://dlms.sharur.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61e.png?v=666d1e6b6e4" class="not-responsive emoji emoji-android emoji--disappointed" style="height:23px;width:auto;vertical-align:middle" title="):" alt="😞" /></p>
<pre><code class="language-hex">00 01 00 01 00 01 00 12 C4 01 C1 00 02 02 06 01 31 2D 00 02 02 0F 00 16 1E
</code></pre>
<ul>
<li><code>06 01 31 2D 00</code>: Double-Long-Unsigned <code>20,000,000 Wh</code> (20,000 kWh)</li>
<li><code>0F 00</code>: Scaler <code>0</code> ($10^0$)</li>
<li><code>16 1E</code>: Unit <code>30 [Wh]</code></li>
</ul>
]]></description><link>https://dlms.sharur.org/post/228</link><guid isPermaLink="true">https://dlms.sharur.org/post/228</guid><dc:creator><![CDATA[alex_turner]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:47 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:45 GMT]]></title><description><![CDATA[<p dir="auto">And for cumulative energy, we migrated our database schema from <code>FLOAT</code> to <code>NUMERIC(18, 4)</code> / <code>BIGINT</code>, preserving 100% of Wh billing increments.</p>
]]></description><link>https://dlms.sharur.org/post/227</link><guid isPermaLink="true">https://dlms.sharur.org/post/227</guid><dc:creator><![CDATA[elena_rostova]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:45 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:43 GMT]]></title><description><![CDATA[<p dir="auto">We audited our field data collection scripts and found 3 custom parsers reading <code>scaler</code> via <code>ord(byte)</code> without signed conversion. Fixing this eliminated the $10^{253}$ current spikes across our entire AMI dashboard!</p>
]]></description><link>https://dlms.sharur.org/post/226</link><guid isPermaLink="true">https://dlms.sharur.org/post/226</guid><dc:creator><![CDATA[carlos_mendez]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:43 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:41 GMT]]></title><description><![CDATA[<p dir="auto">Here is how a compliant decoder should parse Tag <code>0x0F</code> (Integer8):</p>
<pre><code class="language-python"># Compliant Signed Int8 Unpacking:
import struct

def parse_scaler(scaler_byte):
    # struct.unpack('b') reads signed 8-bit integer (-128 to +127)
    return struct.unpack('b', bytes([scaler_byte]))[0]

# Testing with 0xFD:
scaler = parse_scaler(0xFD)
print(f"Parsed Scaler: {scaler}") # Outputs: -3
</code></pre>
]]></description><link>https://dlms.sharur.org/post/225</link><guid isPermaLink="true">https://dlms.sharur.org/post/225</guid><dc:creator><![CDATA[sarah_jenkins]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:41 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:38 GMT]]></title><description><![CDATA[<p dir="auto">Let's review the standard units table in DLMS Blue Book:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align:center">Unit Enum</th>
<th style="text-align:left">Symbol</th>
<th style="text-align:left">Physical Quantity</th>
<th style="text-align:center">Standard Scaler</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong>30</strong></td>
<td style="text-align:left"><code>Wh</code></td>
<td style="text-align:left">Active Energy</td>
<td style="text-align:center"><code>0</code> ($10^0$)</td>
</tr>
<tr>
<td style="text-align:center"><strong>31</strong></td>
<td style="text-align:left"><code>kWh</code></td>
<td style="text-align:left">Active Energy</td>
<td style="text-align:center"><code>3</code> ($10^3$)</td>
</tr>
<tr>
<td style="text-align:center"><strong>32</strong></td>
<td style="text-align:left"><code>varh</code></td>
<td style="text-align:left">Reactive Energy</td>
<td style="text-align:center"><code>0</code></td>
</tr>
<tr>
<td style="text-align:center"><strong>33</strong></td>
<td style="text-align:left"><code>A</code></td>
<td style="text-align:left">Current</td>
<td style="text-align:center"><code>-3</code> (mA $\to$ A) or <code>-2</code></td>
</tr>
<tr>
<td style="text-align:center"><strong>35</strong></td>
<td style="text-align:left"><code>V</code></td>
<td style="text-align:left">Voltage</td>
<td style="text-align:center"><code>-1</code> (0.1V $\to$ V) or <code>0</code></td>
</tr>
<tr>
<td style="text-align:center"><strong>27</strong></td>
<td style="text-align:left"><code>W</code></td>
<td style="text-align:left">Active Power</td>
<td style="text-align:center"><code>0</code> or <code>-1</code></td>
</tr>
</tbody>
</table>
<p dir="auto">Notice that Voltage and Current scalers are almost ALWAYS negative!</p>
]]></description><link>https://dlms.sharur.org/post/224</link><guid isPermaLink="true">https://dlms.sharur.org/post/224</guid><dc:creator><![CDATA[marcus_vance]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:38 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:36 GMT]]></title><description><![CDATA[<p dir="auto">Elena's point regarding IEEE 754 precision is critical for utility MDMS architectures.</p>
<h3>The Correct Datatype Standard:</h3>
<p dir="auto">In all billing and data ingestion pipelines:</p>
<ol>
<li><strong>Never use <code>float</code> (32-bit)</strong> for energy quantities;</li>
<li><strong>Use <code>Double</code> (float64: 53-bit mantissa $\implies 9 \times 10^{15}$ exact integers)</strong> or <strong>Fixed-Point Decimal (Python <code>decimal.Decimal</code>, Java <code>BigDecimal</code>)</strong>;</li>
<li>Perform all aggregation using raw integer arithmetic before applying the scaler.</li>
</ol>
]]></description><link>https://dlms.sharur.org/post/223</link><guid isPermaLink="true">https://dlms.sharur.org/post/223</guid><dc:creator><![CDATA[alex_turner]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:36 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:34 GMT]]></title><description><![CDATA[<p dir="auto">David's mathematical breakdown is spot on. Now let's address the second issue: <strong>Float32 Precision Loss on Cumulative Billing Registers</strong>.</p>
<p dir="auto">Smart meters measure cumulative energy in Watt-hours (Wh) or milli-Watt-hours as a <strong>64-bit integer (<code>Double-Long-Unsigned</code> 0x06 or <code>Long64-Unsigned</code> 0x15)</strong>.</p>
<p dir="auto">When a meter accumulates $20{,}000{,}000\text{ Wh}$ ($20{,}000\text{ kWh}$):</p>
<ul>
<li>In IEEE 754 Single Precision (<code>float32</code>), the significand/mantissa is only <strong>24 bits</strong> (approx 7.22 decimal digits of precision).</li>
<li>Maximum exact integer in <code>float32</code>: $2^{24} = 16{,}777{,}216$.</li>
</ul>
<p dir="auto">Beyond 16,777,216 Wh, <code>float32</code> cannot represent individual 1 Wh increments! Adding $1\text{ Wh}$ to $20{,}000{,}000\text{ Wh}$ in <code>float32</code> results in <strong>exact zero change</strong>:<br />
$$20{,}000{,}000.0f + 1.0f = 20{,}000{,}000.0f$$<br />
Over time, thousands of kilowatt-hours are lost to rounding!</p>
]]></description><link>https://dlms.sharur.org/post/222</link><guid isPermaLink="true">https://dlms.sharur.org/post/222</guid><dc:creator><![CDATA[elena_rostova]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:34 GMT</pubDate></item><item><title><![CDATA[Reply to Why does signed 8-bit negative scaler (-3) cause 10^253 overflow and float32 rounding errors in smart metering billing? on Sat, 22 Aug 2026 17:22:32 GMT]]></title><description><![CDATA[<p dir="auto">Sarah, this is the classic <strong>Unsigned vs Signed Byte Decoding Bug</strong> in A-XDR parsing!</p>
<p dir="auto">Per <strong>DLMS Blue Book Ed. 17 Section 4.3.3 (Register Interface Class 3)</strong> and <strong>IEC 62056-62 Table 12</strong>:<br />
Attribute 3 <code>scaler_unit</code> is defined as:</p>
<pre><code class="language-asn1">ScalerUnit ::= Structure {
  scaler: Integer8 (Tag 0x0F), // SIGNED 8-bit integer!
  unit:   Enum     (Tag 0x16)
}
</code></pre>
<p dir="auto">In two's complement 8-bit signed arithmetic:<br />
<code>0xFD</code> is $-3$ ($253 - 256 = -3$).<br />
$$\text{Physical Value} = \text{Raw Value} \times 10^{\text{scaler}} = 5230 \times 10^{-3} = 5.230\text{ A}$$</p>
<p dir="auto">If a parser incorrectly reads Tag <code>0x0F</code> as an <strong>Unsigned Byte</strong> (<code>uint8</code>), it treats <code>0xFD</code> as $+253$, calculating:<br />
$$\text{Corrupted Value} = 5230 \times 10^{+253} = 5.23 \times 10^{256}\text{ A}!$$</p>
]]></description><link>https://dlms.sharur.org/post/221</link><guid isPermaLink="true">https://dlms.sharur.org/post/221</guid><dc:creator><![CDATA[david_miller]]></dc:creator><pubDate>Sat, 22 Aug 2026 17:22:32 GMT</pubDate></item></channel></rss>