Unsolved QString::toShort problem
-
@kshegunov said in QString::toShort problem:
Why should toShort assume that you meant exactly the binary representation
Maybe I'm still sleeping and oversee something. What else should it assume? If I say its hex and pass FFFE - how does toShort() interpret it?
0x100FF is too big for a short and toShort() should return 0/false (and it does). But FFFE is a valid signed short number. -
@jsulm said in QString::toShort problem:
@kshegunov said in QString::toShort problem:
Why should toShort assume that you meant exactly the binary representation
Maybe I'm still sleeping and oversee something. What else should it assume? If I say its hex and pass FFFE - how does toShort() interpret it?
0x100FF is too big for a short and toShort() should return 0/false (and it does). But FFFE is a valid signed short number.@jsulm I completely agree! (although I have the same feeling about sleeping and maybe overseeing something ;-) Maybe it's time to dive into the Qt 4.8.7 source and investigate why QString::toShort() is failing on "FFFE"? (does Qt 5.X also fail on that btw?)
-
@jsulm said in QString::toShort problem:
But FFFE is a valid signed short number.
No it isn't, and that's the point. Start doing the math in your head and see for yourself:
E * 1 + F * 16 + F * 16^2 + F * 16^3
And the last term overflows, which overflow is caught and voila!
If you havechar z = 127;
then:
z += 1;
Is overflowing, no matter whether the value you get is "correct".
-
@kshegunov I still don't get it.
What is the representation of -2 as signed short? Isn't it 0xFFFE?0000 0000 0000 0010 - 2 1111 1111 1111 1101 - invert + 0000 0000 0000 0001 - add 1 1111 1111 1111 1110 -> 0xFFFE
-
OK, here's an exercise to settle the debate. First, assume that QString::toShort() behaves exactly as you expect.
What should each QString (p_*) be initialized to, in order to get
32
for every output line?QString p_oct, p_dec, p_hex, p_r32; // ... Initialize QStrings here ... qDebug() << p_dec.toShort(nullptr, 10); // Returns 32 qDebug() << p_hex.toShort(nullptr, 16); // Returns 32 qDebug() << p_oct.toShort(nullptr, 8); // Returns 32 qDebug() << p_r32.toShort(nullptr, 32); // Returns 32
Next, what should each QString (n_*) be initialized to, in order to get
-32
for every output line?QString n_oct, n_dec, n_hex, n_r32; // ... Initialize QStrings here ... qDebug() << n_oct.toShort(nullptr, 8); // Returns -32 qDebug() << n_dec.toShort(nullptr, 10); // Returns -32 qDebug() << n_hex.toShort(nullptr, 16); // Returns -32 qDebug() << n_r32.toShort(nullptr, 32); // Returns -32
Decide on your answer for all 8 strings first, then post your answer here.
-
I don't get what you don't get about:
0xFFFE
is a positive overflow for parsing & storing into aushort
. Hence the behaviour.One thing that is clear: the implementation of
QString::toShort()
is notstatic_cast<short>(QString::toUShort())
, even if that might have been the way you were tempted to do it.Nobody has looked at it "the other way round". I cannot test because I am Python/PyQt not C++, but what does
QString("-2").toUShort(&ok, 16)
return? In your theory it should be
0xFFFE
, but I am "hoping"(!) it returns an error, just likeQString("FFFE").toShort(&ok, 16)
does?Assuming that is the case, this means we do not have an ambiguity/duplication, whereby both
FFFE
and-2
strings can be parsed as the same number bytoShort()
/toUShort()
(but2
is the only way to write +2). -
toShort makes a toLongLong interpretation first and than casts it to short theres where the "error" comes from:
short QString::toShort(bool *ok, int base) const { long v = toLongLong(ok, base); if (v < SHRT_MIN || v > SHRT_MAX) { if (ok) *ok = false; v = 0; } return (short)v; }
toLongLong will return 65534, (0xFFFE in int64 is positve after all), and that is bigger than SHRT_MAX -> 0 and failed conversion
-
@JonB said in QString::toShort problem:
In your theory it should be 0xFFFE
No, it would not, because -2 is not a hex number...
"I don't get what you don't get about: 0xFFFE is a positive overflow for parsing & storing into a ushort" - we are not talking about unsigned short, but signed short and 0xFFFE is the representation of -2. -
@J.Hilk
In that case, try passing something like0xFFFFFFFE
or0xFFFFFFFFFFFFFFFE
for the string totoShort()
and those who want-2
instead of error should get it?! -
No, it would not, because -2 is not a hex number...
Yes it is! It's as much a hex number as some other base.
-
@JonB said in QString::toShort problem:
In that case, try passing something like 0xFFFFFFFE or 0xFFFFFFFFFFFFFFFE for the string to toShort()
Come on - these numbers are NOT short. We should stay on topic.
-
@jsulm said in QString::toShort problem:
Come on - these numbers are NOT short. We should stay on topic.
I beg your pardon!? I am totally on topic. I was replying to @J-Hilk 's display of the code of
QString::toShort()
. Did you try what I suggested rather than dismissing it as OT? In view of the code shown, I am trying to suggest what0xFFF....
stringtoShort()
will accept as representing a negative number.... -
Nobody wants to try my exercises... (sad face)
-
@JonB Passing 0xFFFFFFFE returns 0
-
@JonB
actually, no take a look at toLongLongqint64 QString::toLongLong(bool *ok, int base) const { #if defined(QT_CHECK_RANGE) if (base != 0 && (base < 2 || base > 36)) { qWarning("QString::toLongLong: Invalid base (%d)", base); base = 10; } #endif bool my_ok; QLocale def_locale; qint64 result = def_locale.d()->stringToLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators); if (my_ok) { if (ok != 0) *ok = true; return result; } QLocale c_locale(QLocale::C); return c_locale.d()->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators); }
I think, haven't looked stringToLongLong up, that here happens stirng lentgh magic, because every combinaion of FFF..E up to to 0xFFFFFFFE is interpretated as the uint value and everything above as -2 (as returning int64 value)
-
-
@JonB said in QString::toShort problem:
Since QString::toLongLong() returns a qint64 (8 bytes), did you try 0xFFFFFFFFFFFFFFFE ?
Returns 0 as well.
And I don't see why it should depend on the length. -
@JonB surprisingly enough
qDebug() << std::numeric_limits<int64_t>::min() << std::numeric_limits<int64_t>::max() << endl << (int64_t)0xFFFFFFFFFFFFFFFE; QString s("0xFFFFFFFFFFFFFFFE"); bool ok; short sh = s.toShort(&ok, 16); qDebug() <<sh << ok; long lg = s.toLongLong(&ok,16); qDebug() << lg << ok;
returns:
-9223372036854775808 9223372036854775807 -2 0 false 0 false
-
@jsulm
It would "depend on the length", as you put it, because as a 64-bit number0xFFFFFFFE != 0xFFFFFFFFFFFFFFFE
. -
@JonB I want to convert a signed short number not long or long long or ...
0xFFFE as signed short is -2 - do you agree (I mean independently from what Qt toShort() thinks it is)?