Skip to content

Commit 8519d84

Browse files
committed
feat(binary-utils): add NAVBinaryCountLeadingZeros function
- Implement function to count leading zeros in 32-bit values
1 parent f56464e commit 8519d84

File tree

5 files changed

+165
-11
lines changed

5 files changed

+165
-11
lines changed

BinaryUtils/NAVFoundation.BinaryUtils.axi

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,4 +366,39 @@ define_function integer NAVBcdToBinary(char value) {
366366
}
367367

368368

369+
/**
370+
* @function NAVBinaryCountLeadingZeros
371+
* @public
372+
* @description Counts the number of leading zero bits in a 32-bit integer.
373+
*
374+
* @param {long} value - The value to analyze
375+
*
376+
* @returns {integer} Number of leading zeros (0-32)
377+
*
378+
* @example
379+
* stack_var long value
380+
* stack_var integer leadingZeros
381+
*
382+
* value = $0000000F // Binary: 00000000 00000000 00000000 00001111
383+
* leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 28
384+
*
385+
* value = $80000000 // Binary: 10000000 00000000 00000000 00000000
386+
* leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 0
387+
*
388+
* value = $00000000 // Binary: 00000000 00000000 00000000 00000000
389+
* leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 32
390+
*/
391+
define_function integer NAVBinaryCountLeadingZeros(long value) {
392+
stack_var integer count
393+
394+
count = 0
395+
396+
while (count < 32 && (value & (1 << (31 - count))) == 0) {
397+
count = count + 1
398+
}
399+
400+
return count
401+
}
402+
403+
369404
#END_IF // __NAV_FOUNDATION_BINARYUTILS__

BinaryUtils/README.md

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ Include the library in your NetLinx project:
3030
Rotates bits of a 32-bit value to the left by the specified count. Bits that are rotated off the left end appear at the right end.
3131

3232
**Parameters:**
33+
3334
- `value` (long): The value to rotate
3435
- `count` (long): Number of positions to rotate left
3536

3637
**Returns:** (long) The rotated value
3738

3839
**Example:**
40+
3941
```netlinx
4042
stack_var long original
4143
stack_var long rotated
@@ -54,6 +56,7 @@ rotated = NAVBinaryRotateLeft(original, 4) // Binary: 00000000 00000000 0000000
5456
Alias for `NAVBinaryRotateLeft`. Rotates bits of a 32-bit value to the left.
5557

5658
**Parameters:**
59+
5760
- `value` (long): The value to rotate
5861
- `count` (long): Number of positions to rotate left
5962

@@ -68,12 +71,14 @@ Alias for `NAVBinaryRotateLeft`. Rotates bits of a 32-bit value to the left.
6871
Rotates bits of a 32-bit value to the right by the specified count. Bits that are rotated off the right end appear at the left end.
6972

7073
**Parameters:**
74+
7175
- `value` (long): The value to rotate
7276
- `count` (long): Number of positions to rotate right
7377

7478
**Returns:** (long) The rotated value
7579

7680
**Example:**
81+
7782
```netlinx
7883
stack_var long original
7984
stack_var long rotated
@@ -92,6 +97,7 @@ rotated = NAVBinaryRotateRight(original, 4) // Binary: 00000000 00000000 000000
9297
Alias for `NAVBinaryRotateRight`. Rotates bits of a 32-bit value to the right.
9398

9499
**Parameters:**
100+
95101
- `value` (long): The value to rotate
96102
- `count` (long): Number of positions to rotate right
97103

@@ -108,12 +114,14 @@ Alias for `NAVBinaryRotateRight`. Rotates bits of a 32-bit value to the right.
108114
Extracts a single bit from a 32-bit value at the specified position.
109115

110116
**Parameters:**
117+
111118
- `value` (long): The value to extract a bit from
112119
- `bit` (long): The bit position to extract (0-31)
113120

114121
**Returns:** (long) 1 if the specified bit is set, 0 otherwise
115122

116123
**Example:**
124+
117125
```netlinx
118126
stack_var long value
119127
stack_var long bitValue
@@ -128,18 +136,59 @@ bitValue = NAVBinaryGetBit(value, 2) // Returns 1 (third bit from right)
128136

129137
---
130138

139+
#### `NAVBinaryCountLeadingZeros(long value)`
140+
141+
Counts the number of leading zero bits in a 32-bit integer. This is useful for determining the position of the most significant bit or calculating the number of bits required to represent a value.
142+
143+
**Parameters:**
144+
145+
- `value` (long): The value to analyze
146+
147+
**Returns:** (integer) Number of leading zeros (0-32)
148+
149+
**Example:**
150+
151+
```netlinx
152+
stack_var long value
153+
stack_var integer leadingZeros
154+
155+
value = $0000000F // Binary: 00000000 00000000 00000000 00001111
156+
leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 28
157+
158+
value = $80000000 // Binary: 10000000 00000000 00000000 00000000
159+
leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 0
160+
161+
value = $00000000 // Binary: 00000000 00000000 00000000 00000000
162+
leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 32
163+
164+
value = $00FF0000 // Binary: 00000000 11111111 00000000 00000000
165+
leadingZeros = NAVBinaryCountLeadingZeros(value) // Returns 8
166+
```
167+
168+
**Use Cases:**
169+
170+
- Determining bit width requirements for variable-length encoding
171+
- Finding the position of the most significant bit
172+
- Calculating logarithm base 2 (floor)
173+
- Implementing priority encoders
174+
- Optimizing compression algorithms
175+
176+
---
177+
131178
### Binary Representation Functions
132179

133180
#### `NAVByteToBitArray(char value)`
134181

135182
Converts a byte to an array of individual bit values. Each bit is represented as a numeric value (0 or 1) in the returned array.
136183

137184
**Parameters:**
185+
138186
- `value` (char): The byte value to convert
139187

140188
**Returns:** (char[8]) Array of 8 bit values (0 or 1)
141189

142190
**Example:**
191+
143192
```netlinx
144193
stack_var char value
145194
stack_var char result[8]
@@ -150,6 +199,7 @@ result = NAVByteToBitArray(value)
150199
```
151200

152201
**Use Cases:**
202+
153203
- Analyzing individual bits of protocol bytes
154204
- Implementing custom bit-level protocols
155205
- Debugging binary data structures
@@ -161,11 +211,13 @@ result = NAVByteToBitArray(value)
161211
Converts a byte to its binary representation as an 8-character string.
162212

163213
**Parameters:**
214+
164215
- `value` (char): The byte value to convert
165216

166217
**Returns:** (char[8]) Binary representation as an 8-character string
167218

168219
**Example:**
220+
169221
```netlinx
170222
stack_var char value
171223
stack_var char result[8]
@@ -176,6 +228,7 @@ result = NAVByteToBinaryString(value)
176228
```
177229

178230
**Use Cases:**
231+
179232
- Debugging and logging binary data
180233
- Display binary values in user interfaces
181234
- Protocol analysis and troubleshooting
@@ -191,11 +244,13 @@ BCD (Binary Coded Decimal) is a binary encoding where each decimal digit (0-9) i
191244
Converts a binary integer to BCD (Binary Coded Decimal) format using the double-dabble algorithm.
192245

193246
**Parameters:**
247+
194248
- `value` (integer): The binary integer to convert (0-9999)
195249

196250
**Returns:** (long) BCD representation of the value
197251

198252
**Example:**
253+
199254
```netlinx
200255
stack_var integer decimal
201256
stack_var long bcd
@@ -208,6 +263,7 @@ bcd = NAVBinaryToBcd(decimal) // Returns $1234 (BCD format)
208263
```
209264

210265
**Use Cases:**
266+
211267
- Sending decimal values to hardware that expects BCD encoding
212268
- Implementing BCD-based protocols
213269
- Interfacing with seven-segment displays
@@ -221,11 +277,13 @@ bcd = NAVBinaryToBcd(decimal) // Returns $1234 (BCD format)
221277
Converts a BCD (Binary Coded Decimal) byte to its binary integer value. Each nibble (4 bits) of the input represents a decimal digit (0-9).
222278

223279
**Parameters:**
280+
224281
- `value` (char): The BCD-encoded byte to convert (0x00-0x99)
225282

226283
**Returns:** (integer) Binary integer representation (0-99)
227284

228285
**Example:**
286+
229287
```netlinx
230288
stack_var char bcdValue
231289
stack_var integer decimal
@@ -238,6 +296,7 @@ decimal = NAVBcdToBinary(bcdValue) // Returns 99
238296
```
239297

240298
**Use Cases:**
299+
241300
- Reading BCD-encoded data from hardware (RTCs, displays, etc.)
242301
- Parsing BCD protocol responses
243302
- Converting BCD values for display or calculation
@@ -305,21 +364,23 @@ NAVErrorLog(NAV_LOG_LEVEL_DEBUG, "'Received byte: ',binaryStr")
305364

306365
If you're updating from an older version of NAVFoundation.BinaryUtils, the following function names have changed:
307366

308-
| Old Function Name | New Function Name | Notes |
309-
|------------------|-------------------|-------|
310-
| `NAVCharToDecimalBinaryString()` | `NAVByteToBitArray()` | Returns numeric bit array instead of string |
311-
| `NAVCharToAsciiBinaryString()` | `NAVByteToBinaryString()` | Returns ASCII string (behavior unchanged) |
312-
| `NAVDecimalToBinary()` | `NAVBinaryToBcd()` | Corrected naming to reflect BCD conversion |
367+
| Old Function Name | New Function Name | Notes |
368+
| -------------------------------- | ------------------------- | ------------------------------------------- |
369+
| `NAVCharToDecimalBinaryString()` | `NAVByteToBitArray()` | Returns numeric bit array instead of string |
370+
| `NAVCharToAsciiBinaryString()` | `NAVByteToBinaryString()` | Returns ASCII string (behavior unchanged) |
371+
| `NAVDecimalToBinary()` | `NAVBinaryToBcd()` | Corrected naming to reflect BCD conversion |
313372

314373
**New function:**
374+
315375
- `NAVBcdToBinary()` - Reverse BCD conversion for reading hardware values
316376

317377
**Migration steps:**
378+
318379
1. Search your codebase for the old function names
319380
2. Replace with the new names according to the table above
320381
3. For BCD operations, verify you're using the correct direction:
321-
- Use `NAVBinaryToBcd()` when sending to hardware
322-
- Use `NAVBcdToBinary()` when reading from hardware
382+
- Use `NAVBinaryToBcd()` when sending to hardware
383+
- Use `NAVBcdToBinary()` when reading from hardware
323384

324385
## Dependencies
325386

__tests__/NAVFoundation-Tests.apw

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -761,12 +761,12 @@
761761
<Comments></Comments>
762762
</File>
763763
</System>
764-
<System IsActive="false" Platform="Netlinx" Transport="Serial" TransportEx="TCPIP">
764+
<System IsActive="true" Platform="Netlinx" Transport="Serial" TransportEx="TCPIP">
765765
<Identifier>BinaryUtils</Identifier>
766766
<SysID>0</SysID>
767767
<TransTCPIP>0.0.0.0</TransTCPIP>
768768
<TransSerial>COM1,115200,8,None,1,None</TransSerial>
769-
<TransTCPIPEx>192.168.10.37|1319|1|NX-2200|ZGFtaWVu|QXZtYWNoMW5lcyE3MjQ5</TransTCPIPEx>
769+
<TransTCPIPEx>192.168.10.38|1319|1|NX-1200|ZGFtaWVu|QXZtYWNoMW5lcyE3MjQ5</TransTCPIPEx>
770770
<TransSerialEx>COM1|38400|8|None|1|None||</TransSerialEx>
771771
<TransUSBEx>|||||</TransUSBEx>
772772
<TransVNMEx>10.0.0.1|1|&lt;Default&gt;</TransVNMEx>
@@ -942,7 +942,7 @@
942942
<Comments></Comments>
943943
</File>
944944
</System>
945-
<System IsActive="true" Platform="Netlinx" Transport="Serial" TransportEx="TCPIP">
945+
<System IsActive="false" Platform="Netlinx" Transport="Serial" TransportEx="TCPIP">
946946
<Identifier>SocketUtils</Identifier>
947947
<SysID>0</SysID>
948948
<TransTCPIP>0.0.0.0</TransTCPIP>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
PROGRAM_NAME='NAVBinaryCountLeadingZeros'
2+
3+
#include 'NAVFoundation.Core.axi'
4+
#include 'NAVFoundation.Testing.axi'
5+
6+
DEFINE_CONSTANT
7+
8+
// Test data: [value, expected]
9+
constant long BINARY_COUNT_LEADING_ZEROS_TESTS[][2] = {
10+
{ $00000000, 32 }, // Test 1: Zero value - all 32 bits are zero
11+
{ $80000000, 0 }, // Test 2: MSB set - no leading zeros
12+
{ $40000000, 1 }, // Test 3: Second MSB set - 1 leading zero
13+
{ $20000000, 2 }, // Test 4: Third MSB set - 2 leading zeros
14+
{ $FFFFFFFF, 0 }, // Test 5: All bits set - no leading zeros
15+
{ $00000001, 31 }, // Test 6: Only LSB set - 31 leading zeros
16+
{ $0000FFFF, 16 }, // Test 7: Lower 16 bits set - 16 leading zeros
17+
{ $000000FF, 24 }, // Test 8: Lower 8 bits set - 24 leading zeros
18+
{ $00008000, 16 }, // Test 9: Bit 15 set - 16 leading zeros
19+
{ $00000080, 24 }, // Test 10: Bit 7 set - 24 leading zeros
20+
{ $0000000F, 28 }, // Test 11: Lower 4 bits set - 28 leading zeros
21+
{ $00FF0000, 8 }, // Test 12: Bits 23-16 set - 8 leading zeros
22+
{ $FF000000, 0 }, // Test 13: Upper byte set - no leading zeros
23+
{ $AAAAAAAA, 0 }, // Test 14: Alternating bits (MSB set) - no leading zeros
24+
{ $55555555, 1 }, // Test 15: Alternating bits (MSB clear) - 1 leading zero
25+
{ $01000000, 7 }, // Test 16: Bit 24 set - 7 leading zeros
26+
{ $00001000, 19 }, // Test 17: Bit 12 set - 19 leading zeros
27+
{ $0010000F, 11 }, // Test 18: Bit 20 and lower 4 bits - 11 leading zeros
28+
{ $00000002, 30 }, // Test 19: Bit 1 set - 30 leading zeros
29+
{ $10000000, 3 } // Test 20: Bit 28 set - 3 leading zeros
30+
}
31+
32+
define_function TestNAVBinaryCountLeadingZeros() {
33+
stack_var integer x
34+
35+
NAVLog("'***************** NAVBinaryCountLeadingZeros *****************'")
36+
37+
for (x = 1; x <= length_array(BINARY_COUNT_LEADING_ZEROS_TESTS); x++) {
38+
stack_var integer result
39+
40+
result = NAVBinaryCountLeadingZeros(type_cast(BINARY_COUNT_LEADING_ZEROS_TESTS[x][1]))
41+
42+
if (!NAVAssertIntegerEqual('Should count leading zeros correctly', BINARY_COUNT_LEADING_ZEROS_TESTS[x][2], result)) {
43+
NAVLogTestFailed(x, itoa(BINARY_COUNT_LEADING_ZEROS_TESTS[x][2]), itoa(result))
44+
continue
45+
}
46+
47+
NAVLogTestPassed(x)
48+
}
49+
}
50+

__tests__/include/binary-utils/binary-utils.axi

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#DEFINE TESTING_NAVBYTETOBINARYSTRING
88
#DEFINE TESTING_NAVBCDTOBINARY
99
#DEFINE TESTING_NAVBINARYTOBCD
10-
10+
#DEFINE TESTING_NAVBINARYCOUNTLEADINGZEROS
1111
#include 'NAVFoundation.Core.axi'
1212
#include 'NAVFoundation.BinaryUtils.axi'
1313
#include 'NAVFoundation.Assert.axi'
@@ -50,6 +50,10 @@
5050
#include 'NAVBinaryToBcd.axi'
5151
#END_IF
5252

53+
#IF_DEFINED TESTING_NAVBINARYCOUNTLEADINGZEROS
54+
#include 'NAVBinaryCountLeadingZeros.axi'
55+
#END_IF
56+
5357
define_function RunBinaryUtilsTests() {
5458
#IF_DEFINED TESTING_NAVBINARYROTATELEFT
5559
TestNAVBinaryRotateLeft()
@@ -86,4 +90,8 @@ define_function RunBinaryUtilsTests() {
8690
#IF_DEFINED TESTING_NAVBINARYTOBCD
8791
TestNAVBinaryToBcd()
8892
#END_IF
93+
94+
#IF_DEFINED TESTING_NAVBINARYCOUNTLEADINGZEROS
95+
TestNAVBinaryCountLeadingZeros()
96+
#END_IF
8997
}

0 commit comments

Comments
 (0)