-3

I need 16383 to be converted to 7F7F but I can only get this to be converted to 3fff or 77377.

I can convert 8192 to hexadecimal string 4000 which is essentially the same thing.

If I use let firstHexa = String(format:"%02X", a) It stops at 3fff hexadecimal for the first number and and 2000 hexadecimal for the second number. here is my code

public func intToHexString(_ int: Int16) -> String {
    var encodedHexa: String = ""
    if int >= -8192 && int <= 8191 {
        let int16 = int + 8192
        //convert to two unsigned Int8 bytes
        let a = UInt8(int16 >> 8 & 0x00ff)
        let b = UInt8(int16 & 0x00ff)
        //convert the 2 bytes to hexadecimals
        let first1Hexa = String(a, radix: 8 )
        let second2Hexa = String(b, radix: 8)
        let firstHexa = String(format:"%02X", a)
        let secondHexa = String(format:"%02X", b)

        //combine the 2 hexas into 1 string with 4 characters...adding 0 to the beggining if only 1 character.
        if firstHexa.count == 1 {
            let appendedFHexa = "0" + firstHexa
            encodedHexa = appendedFHexa + secondHexa
        } else if secondHexa.count == 1 {
            let appendedSHexa = "0" + secondHexa
            encodedHexa = firstHexa + appendedSHexa
        } else {
            encodedHexa = firstHexa + secondHexa
        }
    }
    return encodedHexa
}

Please help ma'ams and sirs! Thanks.

CRey
  • 1,150
  • 2
  • 9
  • 21
  • 1
    I think you would have a substantially easier time (and better code!) if you broke down the problem. First split `UInt16` to 2 `UInt8` bytes, and then convert each byte into a hex string. What if you want to have the 2 `UInt8` results as `UInt8`s? What if you just want to convert a single already-present `UInt8` to a `String`? Your current code mashes the two together, decreasing the reusability . – Alexander Mar 26 '18 at 16:09
  • 3
    `16383` *is* hexadecimal `3FFF`, and you can simply obtain that with `return String(format:"%04X", Int(int))`. – Can you explain why the result should be `7F7F` ? – Martin R Mar 26 '18 at 16:27
  • @MartinR Lets go with the one I got right. 8192, i split it into two bytes which is 32 and 0 and respectively the hexa string of both is 40 and 00, combined together is 4000. 4000 is the answer Im looking for. basically my question is I have an UInt16, how do i split that into two bytes and get the hexa of both bytes? the number in question is 16383. – CRey Mar 26 '18 at 16:42
  • `32` is hex `0x20`, not `0x40`. `8192` is hex `0x2000`, not `0x4000`. – It is not yet clear to me why you expect those results. – Martin R Mar 26 '18 at 16:46
  • I apologize if Im asking my question wrong. I am not looking for the hex of 8192 rather the hex of the 2 bytes after splitting the UInt16(8192) into 2 UInt8. – CRey Mar 26 '18 at 16:51
  • Rey, the `radix` for hexadecimal is `16`, not `8`. – vacawama Mar 26 '18 at 16:52
  • @ReyCerio: Again, the "hex" of 8192 is 2000, and you simply get that with `String(format:"%04X", number)` – Martin R Mar 26 '18 at 16:54
  • 1
    @ReyCerio, 1) why are you adding 8192 when the number is in range -8192...8191, 2) why are you checking the length of `firstHexa` and `secondHexa` when format `"%02X"` will return 2 digits, 3) why are you using radix `8` instead of `16` for hexadecimal, 4) splitting the number into two bytes, converting those to hex and concatening the result gives you the same answer as converting the original number to hex. – vacawama Mar 26 '18 at 17:14
  • @vacawama 1. is just company instruction. 2. you are right, I am not very familiar with hexas. 3. radix 8 gives me the answers the company is asking for which is hexa string "4000" for 8192. 4. yeah, but this process works on 8192, 0, 10240, 4096 but not 16383. 16383 gives me 77377 but I want 7F7F which is what the company is asking for. Basically, If the answer is all digits no letters, it returns the right answer but if the hexa has a letter in it, my code gives the wrong answer. – CRey Mar 26 '18 at 17:56
  • 1
    @ReyCerio: *"the answers the company is asking"* and *"I want 7F7F"* does not help if you don't explain why. What *exactly* is your intToHexString supposed to do? We cannot *guess* what you want. – Martin R Mar 26 '18 at 18:01
  • @MartinR Im given an Int16, I need to split that into 2 bytes. then get the hexa of both bytes and combine them. They gave me 5 test cases and my answer works on 4 out of 5 except for the 16383. I've tried other test cases and I've found that my code only returns digits no letters for example 16383 returns 77377. if i use `String.init(format:value:) it gets the radix 16 (3fff) but i want the radix 8, which the company is saying its (7F7F). Sorry if my question is confusing. – CRey Mar 26 '18 at 18:20
  • 1
    @ReyCerio: *"i want the radix 8, which the company is saying its (7F7F)"* – that makes no sense. Radix 8 uses only the digits 0...7. The hexadecimal representation of 16383 is 3FFF. – Martin R Mar 26 '18 at 18:22
  • 1
    Hmmm. `0x7f * 128 + 0x7f = 16383`. Perhaps they want you to only take 7 bits at a time for your "bytes". In which case `let a = UInt8(int16 >> 7) & 0x7f; let b = UInt8(int16 & 0x7f); let result = String(format: "%02X%02X", a, b)`. This gives "4000" for `8192` and "7F7F" for `16383`. – vacawama Mar 26 '18 at 18:51
  • @vacawama OMFG you are godlike! I did not realize that the ints they gave me are 14bits not 16. Thank you so much. If it was not for you and MartinR pushing me to clarify. We would not have gotten here. Thank you so much again. – CRey Mar 26 '18 at 19:00
  • @vacawama How would I reverse 7F7F to get 16383? Please and Thanks. – CRey Mar 26 '18 at 19:06
  • (slight correction for a) ... Hmmm. 0x7f * 128 + 0x7f = 16383. Perhaps they want you to only take 7 bits at a time for your "bytes". In which case let a = UInt8((int16 >> 7) & 0x7f); let b = UInt8(int16 & 0x7f); let result = String(format: "%02X%02X", a, b). This gives "4000" for 8192 and "7F7F" for 16383 – vacawama Mar 26 '18 at 19:08

1 Answers1

1

From your test cases, it seems like your values are 7 bits per byte.

You want 8192 to convert to 4000. You want 16383 to convert to 7F7F.

Note that:

(0x7f << 7) + 0x7f == 16383

Given that:

let a = UInt8((int16 >> 7) & 0x7f)
let b = UInt8(int16 & 0x7f)
let result = String(format: "%02X%02X", a , b)

This gives:

"4000" for 8128 "7F7F" for 16383


To reverse the process:

let str = "7F7F"
let value = Int(str, radix: 16)!
let result = ((value >> 8) & 0x7f) << 7 + (value & 0x7f)

print(result)  // 16383
vacawama
  • 150,663
  • 30
  • 266
  • 294