3

I would like to input a text string ffff to a int16_t, the value should be -1.

Here is a simple test C++ program:

#include <iostream>
#include <iomanip>
#include <stdint.h>

int main() {
    int16_t num;

    std::cout << "Enter a hexadecimal number: ";
    std::cin >> std::hex >> num;

    std::cout << "Decimal representation: " << num << std::endl;

    return 0;
}

Here is the result of the program:

Enter a hexadecimal number: ffff
Decimal representation: 32767

You see, the result value 32767 is the largest value of int16_t.

So, my guess is that the line std::cin >> std::hex >> num; does not support the Two's complement notation of the hex format?

Aamir
  • 1,974
  • 1
  • 14
  • 18
ollydbg23
  • 1,124
  • 1
  • 12
  • 38
  • This is the correct behavior. The extractor reads into a value of type `long`. Since the result is too large to fit in an `int16_t` it stores the maximum representable value and sets the stream to an error state. See [here](https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt) for details, in particular, item 12. – Pete Becker May 24 '23 at 00:45
  • 1
    Try `std::cin >> std::hex >> reinterpret_cast(num);` – paddy May 24 '23 at 00:50
  • Thanks, for item 12, do you mean the line `Extracts a short value potentially skipping preceding whitespace.`. And do you mean that for a hex string, the extractor can only get a positive value? even the hex string is represent a negative value. – ollydbg23 May 24 '23 at 00:51
  • Hi, @paddy you method works! Thanks. So, basically I think the `>>` operator can only read positive values if the the input string is a hex string. – ollydbg23 May 24 '23 at 01:19
  • Incorrect. It can read negative hex values, if the value is preceded by a minus-sign. _e.g._ the input `-f` will be read as `-15` when the destination is a signed integer. – paddy May 24 '23 at 02:17
  • @paddy Oh, you are right. As a conclusion, it can read a negative hex notation such as `-f` which is `-15` for `int16_t`, but it can't read the two's complement hex notation such as `ffff` which is `-1` for `int16_t`. – ollydbg23 May 24 '23 at 02:49
  • 1
    Correct, because `ffff` is a _positive_ integer. In the same way, if you were in base-10 you would not expect the value `65535` to be considered negative. Instead, these values exceed the maximum value that can be represented in a 16-bit signed integer. Therefore the truncation rules apply, as per the documentation link Pete Becker provided. – paddy May 24 '23 at 02:55
  • Hi, guys, it looks like the below code works correctly, it just got the `-1` value. Here is the code `int16_t value = std::stoi("ffff", nullptr, 16);`. So, it looks like `std::stoi` function can handle the two's complement hex notation. – ollydbg23 May 24 '23 at 08:18

1 Answers1

0

Also, to get around this, you can just turn num into a uint16_t and then cast num as a int16_t when you use it.

uint16_t num;
std::cin >> std::hex >> num;
std::cout << (int16_t)num;
return 0;
  • Yes, this works. In-fact, I have a `int16_t` variable to fill. I think your answer can be improved by paddy's comment. Can you add it to your answer? Thanks. – ollydbg23 May 24 '23 at 01:22