greatscottgadgets / python-usb-protocol

python library providing utilities, data structures, constants, parsers, and tools for working with USB data
BSD 3-Clause "New" or "Revised" License
55 stars 32 forks source link

fix BCD fields encoding #5

Closed dokthar closed 4 years ago

dokthar commented 4 years ago

For some case the encode function was raising AssertionError despite the BCD value beeing correct (in this case it was 1.11).

There is two main modification in the version I propose:

First the added rounding before converting the "percent" to an integer. This may seems odd but it is actually to "correct" the error introduce by the multiplication.

Second the comparison is done "after" conversion by recreating the floating point value from the integer and percent variables. This is to make sure that the value in the descriptor is the same as intended.

I've made sure that all correct values (that can be stored in bcd fields) doesn't raise an error when passed to the encode function.

I've used the following program to test the new implementation:

for obj in [float(f"{i:02}.{p:02}") for i in range(100) for p in range(100)]:
    integer = int(obj) % 100
    percent = int(round(obj * 100)) % 100
    if float(f"{integer:02}.{percent:02}") != obj:
        print (f"BCD conversion error: {integer:02}.{percent:02} != {obj}")
ktemkin commented 4 years ago

Looks good to me -- thanks a lot. :)