Russian Qt Forum

Qt => Общие вопросы => Тема начата: 8Observer8 от Март 14, 2014, 12:35



Название: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 12:35
Привет!

Корректно ли такое преобразование из QString в qint64 с помощью метода toULongLong()? Если нет, то какой способ лучше?

Заранее спасибо за ответ.

Код
C++ (Qt)
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   QString str("1394790029894");
 
   qint64 t = str.toULongLong();
 
   QDateTime time;
   time.setMSecsSinceEpoch(t);
 
   qDebug() << time.toString();
 
   return a.exec();
}
 


Название: Re: Преобразование из QString в qint64
Отправлено: OKTA от Март 14, 2014, 13:11
Чем не преобразование?  :)
Разве что quint64 вместо qint64, раз toULongLong используешь


Название: Re: Преобразование из QString в qint64
Отправлено: Johnik от Март 14, 2014, 13:19
qglobal.h
Код:
typedef qint64 qlonglong;
typedef quint64 qulonglong;


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 13:31
Я думал, что toULongLong() не гарантирует, что он вернёт 64-x разрядное число. По сообщению Johnik вижу, что разрядность гарантирванно совпадает. Несмотря на то, что метод setMSecsSinceEpoch() принимает qint64, а мы ему подсунем quint64, ничего страшного не произойдёт. Неявное преобразование из quint64 в qint64 - безопасно, так как не происходит усечения значения. Всем спасибо большое! :)


Название: Re: Преобразование из QString в qint64
Отправлено: kambala от Март 14, 2014, 14:31
Несмотря на то, что метод setMSecsSinceEpoch() принимает qint64, а мы ему подсунем quint64, ничего страшного не произойдёт. Неявное преобразование из quint64 в qint64 - безопасно, так как не происходит усечения значения. Всем спасибо большое! :)
это то же самое, как если сказать «если мы методу, принимающему char, подсунем unsigned char, то ведь ничего страшного не произойдёт». вот подсунь такому методу число 128 и узнаешь ;)


Название: Re: Преобразование из QString в qint64
Отправлено: OKTA от Март 14, 2014, 14:59
Откройте мне глаза! Когда используется обратный код, а когда дополнительный?


Название: Re: Преобразование из QString в qint64
Отправлено: kambala от Март 14, 2014, 15:01
обратный код — это просто инвертирование битов числа (унарный оператор ~), а дополнительный — умножение на -1 (к инвертированному числу добавить 1)

нет, кажется наоборот (термины перепутал)


Название: Re: Преобразование из QString в qint64
Отправлено: OKTA от Март 14, 2014, 15:04
Да нет, вроде не перепутал, все верно!

Знаковые переменные хранятся в дополнительном коде, верно?


Название: Re: Преобразование из QString в qint64
Отправлено: kambala от Март 14, 2014, 15:17
отрицательные значения — да


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 17:17
Я понял о чём речь. Если мы попытаемся привести число 128 типа "unsigned char" к типу "signed char", то получим выход за диапазон допустимых значений:

unsigned char: [0, 255]
signed char: [-128, 127]


Название: Re: Преобразование из QString в qint64
Отправлено: OKTA от Март 14, 2014, 18:02
Попробуй и посмотри, что будет  :)

Код:
int main()
{   
    char a;
    a = 128;
    printf ("%d", a);
    return 0;
}


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 18:16
Если написать просто "char", то система решит, что это "signed char". 128 - это выход за допустимый диапазон для "signed char". Поэтому нужно явно указать "unsigned char":

Код
C++ (Qt)
#include <QCoreApplication>
#include <stdio.h>
 
int main(int argc, char *argv[])
{
   QCoreApplication app(argc, argv);
 
   unsigned char a;
   a = 128;
   printf ("%d", a);
 
   return app.exec();
}
 


Название: Re: Преобразование из QString в qint64
Отправлено: OKTA от Март 14, 2014, 18:18
Но таки работать будет  :)


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 18:29
Зависит от системы. На моей системе "char" преобразуется к "signed char", поэтому если написать: "char a;", то вывод будет: "-128". Если написать явно: "unsigned char a;", то вывод будет: 128

На других системах "char" преобразуется к "unsigned char", поэтому вывод будет: 128

Интересно, что в стандарте написано по этому поводу? Может там написано, что "char" преобразуется либо к "unsigned char", либо "signed char" - на усмотрение разработчиков компиляторов?


Название: Re: Преобразование из QString в qint64
Отправлено: Old от Март 14, 2014, 18:34
На других системах "char" преобразуется к "unsigned char", поэтому вывод будет: 128
Это на каких таких системах? :)


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 18:38
Это на каких таких системах? :)

OKTA же написал:

Но таки работать будет  :)

Отсюда можно сделать вывод, что у него работает и выводит: 128


Название: Re: Преобразование из QString в qint64
Отправлено: OKTA от Март 14, 2014, 18:42
Я хотел сказать, что никаких ошибок выхода за диапазон значений не будет )))

насчет signed-unsigned можно заглянуть в такой файл limits.h. В нем должна быть достоверная информация, на сколько мне известно)
Вот, что у меня понаписали)
Код:
#define CHAR_BIT      8         /* number of bits in a char */
#define SCHAR_MIN   (-128)      /* minimum signed char value */
#define SCHAR_MAX     127       /* maximum signed char value */
#define UCHAR_MAX     0xff      /* maximum unsigned char value */

#ifndef _CHAR_UNSIGNED
#define CHAR_MIN    SCHAR_MIN   /* mimimum char value */
#define CHAR_MAX    SCHAR_MAX   /* maximum char value */
#else
#define CHAR_MIN      0
#define CHAR_MAX    UCHAR_MAX
#endif  /* _CHAR_UNSIGNED */

А еще вот)
из http://cpp0x.centaur.ath.cx/basic.fundamental.html

3.9.1 Fundamental types

1Objects declared as characters (char) shall be large enough to store any member of the implementation’s basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (3.11); that is, they have the same object representation. For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 18:48
Как же не будет? А что это тогда, если не ошибка? Я хочу вывести 128: "char a = 128;" А на экране вижу: -128. Это произошло из-за выхода из допустимого диапазона, который для signed char: [-128; 127]. Поэтому и нужно было явно написать: "unsigned char a = 128;"

По поводу "других систем" я перепутал с расширением знака при преобразовании из char в int.


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 19:04
Кто может кроме программиста определить _CHAR_UNSIGNED? Может же быть такое, что где-нибудь в настройках среды определят _CHAR_UNSIGNED разработчики среды? Ведь от этого зависит, будет ли преобразовываться "char" к "unsigned char" или к "signed char".


Название: Re: Преобразование из QString в qint64
Отправлено: kambala от Март 14, 2014, 20:02
«ошибка» имелось в виду на стадии компиляции. максимум, что компилятор может на такое сказать — это предупреждение.

у некоторых компиляторов есть настройка «always interpret char as unsigned char».


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 20:32
у некоторых компиляторов есть настройка «always interpret char as unsigned char».

Я так понимаю, что есть три способа настройки компилятора:
1) Передать через командную строку это настройку при запуске компилятора
2) Через среду программирования (которая сама в конечном итоге запускает компилятор в режиме командной строки и передаёт эту настройку
3) С помощью препроцессора определить: #define _CHAR_UNSIGNED

Так ли я всё понял?


Название: Re: Преобразование из QString в qint64
Отправлено: kambala от Март 14, 2014, 21:26
1 и 2 — да, 3 — не уверен, что это хороший способ. компилятор как раз сам этот дефайн и задаст если нужно сразу для всего проекта.


Название: Re: Преобразование из QString в qint64
Отправлено: 8Observer8 от Март 14, 2014, 21:49
Большое спасибо! :)


Название: Re: Преобразование из QString в qint64
Отправлено: Igors от Март 15, 2014, 13:04
Неявное преобразование из quint64 в qint64 - безопасно, так как не происходит усечения значения.
Никакого "преобразования" здесь не происходит, т.е. физически это не выливается ни в какой код. В рамках данного типа (или если он "старший") арифметике все равно signed/unsigned, напр
Код
C++ (Qt)
quint64 a = -1;
qint64 b = (a - 1) * 5;  // b = -10
 
Однако если данный тип приводится к старшему - тогда "ой"
Код
C++ (Qt)
char a = -1;
unsigned char b = -1;
int a1 = 1 - a; // a1 = -2
int b1 = 1 - b; // b1 = -254
 
Впрочем резвым любителям СУБД это вряд ли нужно - пусть все unsigned, и все дела!