Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I'm sure I'm doing something wrong #11

Open
RolandasRazma opened this issue Oct 22, 2019 · 7 comments
Open

I'm sure I'm doing something wrong #11

RolandasRazma opened this issue Oct 22, 2019 · 7 comments

Comments

@RolandasRazma
Copy link

RolandasRazma commented Oct 22, 2019

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

@Cosmo
Copy link
Owner

Cosmo commented Jun 17, 2020

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).

@RolandasRazma
Copy link
Author

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

@RolandasRazma
Copy link
Author

hm, this gives different result from what I get

@Cosmo
Copy link
Owner

Cosmo commented Sep 11, 2020

Weird, can you give me an example?

@RolandasRazma
Copy link
Author

 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
Copy link
Author

P.S. tested on 3.0.1

@Cosmo
Copy link
Owner

Cosmo commented Oct 18, 2020

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

  1. Take the first 10 bits (11 1111 1010) as in your first XCTAssertEqual.
  2. 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.
  3. The remaining bits 1 1111 1010 are 506 in decimal.
  4. Together with the sign, its -506

Did I miss anything?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants