BinaryKit icon indicating copy to clipboard operation
BinaryKit copied to clipboard

I'm sure I'm doing something wrong

Open RolandasRazma opened this issue 6 years ago • 7 comments

I'm sure I'm doing something wrong, could you point me right direction please? Im trying to read signed value but not sure how to correctly read negative one.

I added category to accomplish this

extension Binary {
    
    mutating func readSignedBits(quantitiy: Int) throws -> Int {
        
        if try readBit() == 1 {
            let bit = try readBits(quantitiy: quantitiy - 1)

            let bitsReversed = String(String(bit, radix: 2).map({ $0 == "1" ? "0" : "1" }))
            return -Int(bitsReversed, radix: 2)! - 1
        } else {
            return try readBits(quantitiy: quantitiy - 1)
        }
        
    }
    
}

but it doesn't "feel" right

RolandasRazma avatar Oct 22 '19 17:10 RolandasRazma

Hi @RolandasRazma, big sorry — for some reason I didn't notice your issue!

I think, this should do the trick:

extension Binary {
    mutating func readSignedBits(_ quantitiy: UInt8) throws -> Int {
        let multiplicationFactor = (try readBit() == 1) ? -1 : 1
        let value = try readBits(quantitiy - 1)
        return value * multiplicationFactor
    }
}

It's similar of what you do. First, I tell how many bits I actually want to read. Then I read the first bit to determine if the value is positive (0) or negative (1). Then I read the remaining bits and multiply the integer value of those bits by 1 (positive) or by -1 (negative).

Cosmo avatar Jun 17 '20 17:06 Cosmo

hi, no worries, thanks for reply, will try it out

RolandasRazma avatar Jun 17 '20 18:06 RolandasRazma

hm, this gives different result from what I get

RolandasRazma avatar Sep 11 '20 21:09 RolandasRazma

Weird, can you give me an example?

Cosmo avatar Sep 11 '20 21:09 Cosmo

 var binary = Binary(bytes: [252, 100, 99, 4, 254, 129, 98, 19, 254, 3, 200, 192])
 _ = try! binary.readBits(quantitiy: 32)
        
XCTAssertEqual(try binary.readSignedBits(quantitiy: 10), -6) // My implementation returns -6, yours -250
XCTAssertEqual(try binary.readSignedBits(quantitiy: 10), 22)
XCTAssertEqual(try binary.readSignedBits(quantitiy: 10), 132)

RolandasRazma avatar Sep 12 '20 08:09 RolandasRazma

P.S. tested on 3.0.1

RolandasRazma avatar Oct 05 '20 11:10 RolandasRazma

Hmm weird — on my machine try binary.readSignedBits(10) returns -506.

This is what I did for debugging:

  1. I took var binary = Binary(bytes: [252, 100, 99, 4, 254, 129, 98, 19, 254, 3, 200, 192]) from your example

  2. Next is _ = try! binary.readBits(quantity: 32). Which basically means: "skip the first 4 bytes" (side note: i realized that i have a typo in the word "quantity" throughout my repo. whoops!)

  3. Skipping the first 4 bytes leaves the array with [254, 129, 98, 19, 254, 3, 200, 192] (removing the first 4 elements)

  4. [254, 129, 98, 19, 254, 3, 200, 192] in hex is [0xFE, 0x81, 0x62, 0x13, 0xFE, 0x03, 0xC8, 0xC0] and conveniently are 8 bytes which fit in the calculator app.

  5. In the calculator app, it looks like this (see screenshot) and shows me a binary representation. image

  6. Take the first 10 bits (11 1111 1010) as in your first XCTAssertEqual.

  7. The first bit determines if the following 9 bits are positive or negative. In this case, the first bit is 1 which means the integer will be on the negative side.

  8. The remaining bits 1 1111 1010 are 506 in decimal.

  9. Together with the sign, its -506

Did I miss anything?

Cosmo avatar Oct 18 '20 20:10 Cosmo