0

I've been searching for a solution to my problem for days but can't get a spot-on answer when looking at previously answered questions/ blogs / tutorials etc. all over the internet.

My aim is to write a program which takes a decimal number as an input and then calculates the hexadecimal number and also prints the unicode-symbol of said hexadecimal number (\uXXXX). My problem is I can't "convert" the hexadecimal number to unicode. (It has to be written in this format: \uXXXX)

Example:

Input:

122 (= Decimal)

Output:

Hexadecimal: 7A

Unicode: \u007A | Unicode Symbol: Latin small letter "z"

The only thing I've managed to do is print the unicode (\u007A), but I want the symbol ("z"). I thought if the unicode only has 4 numbers/letters, I would just need to "copy" the hexadecimal into the code and fill up the remaining places with 0's and it kinda worked, but as I said I need the symbol not the code. So I tried and tried, but I just couldn't get the symbol. By my understanding, if you want the symbol you need to print it as a string. But when trying it with a string I get the error "illegal unicode escape".

It's like you only can print pre-determined unicodes and not "random" ones generated on the spot in relation of your input.

I'm only a couple days into Java, so apologies if I have missed anything.

Thank you for reading.

My code:

        int dec;
        int quotient;
        int rest;
        int[]hex = new int[10];
        char[]chars = new char[]{
            'F',
            'E',
            'D',
            'C',
            'B',
            'A'
        };
        String unicode;
// Input Number
        System.out.println("Input decimal number:");
        Scanner input = new Scanner(System.in);
        dec = input.nextInt();
//
// "Converting to hexadecimal
        quotient = dec / 16;           
        rest = dec % 16;
        hex[0] = rest;

        int j = 1;
        while (quotient != 0) {
            rest = quotient % 16;
            quotient = quotient / 16;
            hex[j] = rest;
            j++;
        }
//

        /*if (j == 1) {
            unicode = '\u000';
        }
        if (j == 2) {
            unicode = '\u00';
        }
        if (j == 3) {
            unicode = '\u0';
        }*/

        System.out.println("Your number: " + dec);
        System.out.print("The corresponding Hexadecimal number: ");

        for (int i = j - 1; i >= 0; i--) {
            if (hex[i] > 9) {
                if (j == 1) {
                    unicode = "\u000" + String.valueOf(chars[16 - hex[i] - 1]);
                }
                if (j == 2) {
                    unicode = "\u00" + String.valueOf(chars[16 - hex[i] - 1]);
                }
                if (j == 3) {
                    unicode = "\u0" + String.valueOf(chars[16 - hex[i] - 1]);
                }
                System.out.print(chars[16 - hex[i] - 1]);
            } else {
                if (j == 1) {
                    unicode = "\u000" + Character.valueOf[hex[i]);
                }
                if (j == 2) {
                    unicode = "\u00" + Character.valueOf(hex[i]);
                }
                if (j == 3) {
                    unicode = "\u0" + Character.valueOf(hex[i]);
                }
                System.out.print(hex[i]);
            }
        }

        System.out.println();
        System.out.print("Unicode: " + (unicode));
    }

It's not an advanced code whatsoever, I wrote it exactly how I would calculate it on paper. Dividing the number through 16 until I get a 0 and what remains while doing so is the hexadecimal equivalent. So I put it in a while loop, since I would divide the number n-times until I got 0, the condition would be to repeat the division until the quotient equals zero. While doing so the remains of each division would be the numbers/letters of my hexadecimal number, so I need them to be saved. I choose an integer array to do so. Rest (remains) = hex[j]. I also threw a variable in the called "j", so I would now how many times the division was repeated. So I could determine how long the hexadecimal is. In the example it would 2 letters/numbers long (7A), so j = 2. The variable would then be used to determine how many 0's I would need to fill up the unicode with. If I have only 2 letters/numbers, it means there are 2 empty spots after \u, so we add two zeros, to get \u007A instead of \u7A.

Also the next if-command replaces any numbers higher than 9 with a character from the char array above. Basically just like you would do on paper.

I'm very sorry for this insanely long question.

moeux
  • 191
  • 15
  • Adding the code you've tried may help someone answer your question and pinpoint where your issue is. – Jake Luby Oct 15 '19 at 15:17
  • `(char) dec` should do, a bit more complete `Character.toChars(dec)` – user85421 Oct 15 '19 at 15:40
  • Note: you cannot print all unicode code points: some are just combining characters, in that case you should add a placeholder (you find often the dashed circle), Other special characters: just print the name. (and look for Korean code point) – Giacomo Catenazzi Oct 16 '19 at 13:31

2 Answers2

1

U+007A is the 3 bytes int code pointer.

\u007A is the UTF-16 char.

A Unicode code pointer, symbol, sometimes is converted to two chars and then the hexadecimal numbers do not agree. Using code pointers hence is best. As UTF-16 is just an encoding scheme for two-bytes representation, where the surrogate pairs for 3 byte Unicode numbers do not contain / or such (high bit always 1).

int hex = 0x7A;
hex = Integer.parseUnsignedInt("007A", 16);
char ch = (char) hex;
String stringWith1CodePoint = new String(new int[] { hex }, 0, 1);
int[] codePoints = stringWith1CodePoint.codePoints().toArray();

String s = ""; // U+1D11E = "\uD834\uDD1E"
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Thank you very much for your incredibly fast answer. Also thanks for clearing up things for me, I'm afraid my current knowledge on this subject gives me a hard time to comprehend this fully. I'll look into it, thank you. – moeux Oct 15 '19 at 15:49
0

You can simply use System.out.printf or String.format to do what you want.

Example:

int decimal = 122;

System.out.printf("Hexadecimal: %X\n", decimal);
System.out.printf("Unicode: u%04X\n", decimal);
System.out.printf("Latin small letter: %c\n", (char)decimal);

Output:

Hexadecimal: 7A
Unicode: u007A
Latin small letter: z
Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • Thank you very much, this could have saved me so much time. Unfortunately I wasn't as smart before, I'll look into your answer to fully comprehend what each command does. Again, thank you very much for your beginner-friendly answer. – moeux Oct 15 '19 at 15:54
  • So I looked into the Formatter (?) blog on here [Formatter (Oracle Docs)](https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax) and as far as I understood: printf = format your output | % is used to add a conversion | %X formats the output to a hexadecimal | %c formats the output to an unicode character. The only thing I don't understand is the u%04X or more how it works. I suppose "u" is printed as usual but what does the 04 exactly do? I could not find this "04" on the site mentioned above. @Christos – moeux Oct 15 '19 at 16:29
  • This is zero padding format. The `u` is just the character you want to print before the padded string, the `04` represents the zero padding with `4` zeros. You can search for `printf` zero padding for more details for example here http://www.java2s.com/Tutorial/Java/0120__Development/Printingwiththe0zeroflagfillsinleadingzeros.htm – Christos Lytras Oct 15 '19 at 16:35