Russian Qt Forum
Ноябрь 22, 2024, 11:46 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: MSVC 2015 чудит: float -> double  (Прочитано 10667 раз)
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #15 : Июнь 28, 2018, 01:05 »


Похоже в случае с float он снимает со стека float и потом его переводит в double, а в случае с double сразу double и снимает, хотя dotProduct() float возвращает. Может тут собака порылась Улыбающийся.


Да, так и есть. А получится войти в dotProduct и посмотреть, что он возвращает реально? Мб кутешники криво собрали? (хотя qreal уже давно везде double, а тут явно указан float). То есть версии на 5.2 я бы поставил на косяк версий, а тут даже не знаю...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Июнь 28, 2018, 10:01 »

Как охотно постится предмет по существу бесполезный Улыбающийся Что баг компилятора - очевидно по первым строкам стартового поста. Тогда что мы хотим? Найти точно ту (неправильную) команду? Ну допустим даже нашли, проблему это не решит, компилятор не изменить. Найти кукую-то опцию компилятора? Шансов мало и это решается "методом втыка"

Использовать точное сравнение для double можно, но случай это довольно редкий, практически любой код пестрит чем-то типа NEAR_ONE, NEAR_ZERO и.т.п. А конкретно в случае скалярного произведения требование  точного совпадения вообще ничем не оправдано. Так может просто найти все вызовы dotProduct и вставить проверки с каким-то epsilon ?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #17 : Июнь 28, 2018, 10:11 »

Как охотно постится предмет по существу бесполезный Улыбающийся Что баг компилятора - очевидно по первым строкам стартового поста. Тогда что мы хотим? Найти точно ту (неправильную) команду? Ну допустим даже нашли, проблему это не решит, компилятор не изменить. Найти кукую-то опцию компилятора? Шансов мало и это решается "методом втыка"

Использовать точное сравнение для double можно, но случай это довольно редкий, практически любой код пестрит чем-то типа NEAR_ONE, NEAR_ZERO и.т.п. А конкретно в случае скалярного произведения требование  точного совпадения вообще ничем не оправдано. Так может просто найти все вызовы dotProduct и вставить проверки с каким-то epsilon ?
Если это баг компилятора, то нужно майкрософтовцам об этом сообщить. Но возможно это баг сборки Кьюта. И тема намного полезнее твоих тем по решению твоих проблем.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #18 : Июнь 28, 2018, 10:56 »

В MinGW 5.3.0 на Windows и GCC 5.3.1 на Linux бага нет. И в MinGW и в GCC получается строго 1.00000.... безо всяких хвостов-сюрпризов  в мантиссе.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Июнь 28, 2018, 11:14 »

В MinGW 5.3.0 на Windows и GCC 5.3.1 на Linux бага нет. И в MinGW и в GCC получается строго 1.00000.... безо всяких хвостов-сюрпризов  в мантиссе.
Спокойнее к этому относитесь, не тратьте время на всякие проверки. Ну да, это в такой-о версии MSVC не работает, у меня подобных ситуевин было с десяток (если не 2). Это ж чудесный компилятор, там возможно мноогое  (что и не снилось стандарту Улыбающийся). Как говорится "умный гору обойдет".
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #20 : Июнь 28, 2018, 13:02 »

Да, так и есть. А получится войти в dotProduct и посмотреть, что он возвращает реально? Мб кутешники криво собрали? (хотя qreal уже давно везде double, а тут явно указан float). То есть версии на 5.2 я бы поставил на косяк версий, а тут даже не знаю...

В debug сборке вычисляется нормально (чистая 1.00000000000000000000).

Если упростить пример до:
Код
C++ (Qt)
#include <QtCore>
#include <QtGui>
 
int main(int argc, char* argv[])
{
   QVector2D   v1(8.10837e-09, -1);
   QVector2D   v2(4.45843e-07, -1);
 
   volatile float  f1 = QVector2D::dotProduct(v1, v2);
   volatile double d1 = f1;
   volatile double d2 = QVector2D::dotProduct(v1, v2);
 
   return 0;
}

То для него release сборка с оптимизацией выглядит так (если я всё правильно сделал):
Код:
        4    {
0x1361000                    sub     esp,18h
        8        volatile float  f1 = QVector2D::dotProduct(v1, v2);
0x1361003  <+0x0003>         lea     eax,[esp+8]
        5        QVector2D   v1(8.10837e-09, -1);
0x1361007  <+0x0007>         mov     dword ptr [esp+10h],320B4CFDh
        8        volatile float  f1 = QVector2D::dotProduct(v1, v2);
0x136100f  <+0x000f>         push    eax
0x1361010  <+0x0010>         lea     eax,[esp+14h]
        5        QVector2D   v1(8.10837e-09, -1);
0x1361014  <+0x0014>         mov     dword ptr [esp+18h],0BF800000h
        8        volatile float  f1 = QVector2D::dotProduct(v1, v2);
0x136101c  <+0x001c>         push    eax
        6        QVector2D   v2(4.45843e-07, -1);
0x136101d  <+0x001d>         mov     dword ptr [esp+10h],34EF5C32h
0x1361025  <+0x0025>         mov     dword ptr [esp+14h],0BF800000h
        8        volatile float  f1 = QVector2D::dotProduct(v1, v2);
0x136102d  <+0x002d>         call    dword ptr [FloatDouble!_imp_?dotProductQVector2DSAMABV1 (01362034)]
0x1361033  <+0x0033>         fstp    dword ptr [esp+8]
        9        volatile double d1 = f1;
0x1361037  <+0x0037>         movss   xmm0,dword ptr [esp+8]
        10        volatile double d2 = QVector2D::dotProduct(v1, v2);
0x136103d  <+0x003d>         lea     eax,[esp+10h]
0x1361041  <+0x0041>         cvtps2pd xmm0,xmm0
0x1361044  <+0x0044>         push    eax
0x1361045  <+0x0045>         lea     eax,[esp+1Ch]
0x1361049  <+0x0049>         push    eax
0x136104a  <+0x004a>         movsd   mmword ptr [esp+10h],xmm0
0x1361050  <+0x0050>         call    dword ptr [FloatDouble!_imp_?dotProductQVector2DSAMABV1 (01362034)]
0x1361056  <+0x0056>         fstp    qword ptr [esp+20h]
        12        return 0;
0x136105a  <+0x005a>         xor     eax,eax
        13    }
0x136105c  <+0x005c>         add     esp,28h
0x136105f  <+0x005f>         ret

Исходник QVector2D::dotProduct (Qt 5.10.0):
Код
C++ (Qt)
float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
{
   return v1.xp * v2.xp + v1.yp * v2.yp;
}

Асм (Qt 5.10.0 MSVC 2015 32-bit):
Код:
        Qt5Gui!QVector2D::dotProduct [c:\users\qt\work\qt\qtbase\src\gui\math3d\qvector2d.cpp @ 346]:
0xfc672c0                    mov     ecx,dword ptr [esp+4]
0xfc672c4  <+0x0004>         mov     eax,dword ptr [esp+8]
0xfc672c8  <+0x0008>         fld     dword ptr [ecx+4]
0xfc672cb  <+0x000b>         fmul    dword ptr [eax+4]
0xfc672ce  <+0x000e>         fld     dword ptr [ecx]
0xfc672d0  <+0x0010>         fmul    dword ptr [eax]
0xfc672d2  <+0x0012>         faddp   st(1),st
0xfc672d4  <+0x0014>         ret

Так что, кто понимает тонкости в этих закорючках, можете расшифровывать Улыбающийся.

PS. Для сравнения асм debug сборки:
Код:
        4    {
0x901000                    push    ebp
0x901001  <+0x0001>         mov     ebp,esp
0x901003  <+0x0003>         sub     esp,24h
        5        QVector2D   v1(8.10837e-09, -1);
0x901006  <+0x0006>         push    ecx
0x901007  <+0x0007>         movss   xmm0,dword ptr [FloatDouble!_realbf800000 (00904a48)]
0x90100f  <+0x000f>         movss   dword ptr [esp],xmm0
0x901014  <+0x0014>         push    ecx
0x901015  <+0x0015>         movss   xmm0,dword ptr [FloatDouble!_real (00904a40)]
0x90101d  <+0x001d>         movss   dword ptr [esp],xmm0
0x901022  <+0x0022>         lea     ecx,[ebp-14h]
0x901025  <+0x0025>         call    dword ptr [FloatDouble!_imp_??0QVector2DQAEMMZ (00903038)]
        6        QVector2D   v2(4.45843e-07, -1);
0x90102b  <+0x002b>         push    ecx
0x90102c  <+0x002c>         movss   xmm0,dword ptr [FloatDouble!_realbf800000 (00904a48)]
0x901034  <+0x0034>         movss   dword ptr [esp],xmm0
0x901039  <+0x0039>         push    ecx
0x90103a  <+0x003a>         movss   xmm0,dword ptr [FloatDouble!_real (00904a44)]
0x901042  <+0x0042>         movss   dword ptr [esp],xmm0
0x901047  <+0x0047>         lea     ecx,[ebp-0Ch]
0x90104a  <+0x004a>         call    dword ptr [FloatDouble!_imp_??0QVector2DQAEMMZ (00903038)]
        8        volatile float  f1 = QVector2D::dotProduct(v1, v2);
0x901050  <+0x0050>         lea     eax,[ebp-0Ch]
0x901053  <+0x0053>         push    eax
0x901054  <+0x0054>         lea     ecx,[ebp-14h]
0x901057  <+0x0057>         push    ecx
0x901058  <+0x0058>         call    dword ptr [FloatDouble!_imp_?dotProductQVector2DSAMABV1 (00903034)]
0x90105e  <+0x005e>         add     esp,8
0x901061  <+0x0061>         fstp    dword ptr [ebp-4]
        9        volatile double d1 = f1;
0x901064  <+0x0064>         movss   xmm0,dword ptr [ebp-4]
0x901069  <+0x0069>         cvtss2sd xmm0,xmm0
0x90106d  <+0x006d>         movsd   mmword ptr [ebp-1Ch],xmm0
        10        volatile double d2 = QVector2D::dotProduct(v1, v2);
0x901072  <+0x0072>         lea     edx,[ebp-0Ch]
0x901075  <+0x0075>         push    edx
0x901076  <+0x0076>         lea     eax,[ebp-14h]
0x901079  <+0x0079>         push    eax
0x90107a  <+0x007a>         call    dword ptr [FloatDouble!_imp_?dotProductQVector2DSAMABV1 (00903034)]
0x901080  <+0x0080>         add     esp,8
0x901083  <+0x0083>         fstp    qword ptr [ebp-24h]
        12        return 0;
0x901086  <+0x0086>         xor     eax,eax
        13    }
0x901088  <+0x0088>         mov     esp,ebp
0x90108a  <+0x008a>         pop     ebp
0x90108b  <+0x008b>         ret

Код:
        Qt5Guid!QVector2D::dotProduct [c:\users\qt\work\qt\qtbase\src\gui\math3d\qvector2d.cpp @ 346]:
0x67ff1e10                    push    ebp
0x67ff1e11  <+0x0001>         mov     ebp,esp
0x67ff1e13  <+0x0003>         push    ecx
0x67ff1e14  <+0x0004>         mov     eax,dword ptr [ebp+8]
0x67ff1e17  <+0x0007>         mov     ecx,dword ptr [ebp+0Ch]
0x67ff1e1a  <+0x000a>         movss   xmm0,dword ptr [eax]
0x67ff1e1e  <+0x000e>         mulss   xmm0,dword ptr [ecx]
0x67ff1e22  <+0x0012>         mov     edx,dword ptr [ebp+8]
0x67ff1e25  <+0x0015>         mov     eax,dword ptr [ebp+0Ch]
0x67ff1e28  <+0x0018>         movss   xmm1,dword ptr [edx+4]
0x67ff1e2d  <+0x001d>         mulss   xmm1,dword ptr [eax+4]
0x67ff1e32  <+0x0022>         addss   xmm0,xmm1
0x67ff1e36  <+0x0026>         movss   dword ptr [ebp-4],xmm0
0x67ff1e3b  <+0x002b>         fld     dword ptr [ebp-4]
0x67ff1e3e  <+0x002e>         mov     esp,ebp
0x67ff1e40  <+0x0030>         pop     ebp
0x67ff1e41  <+0x0031>         ret
« Последнее редактирование: Июнь 28, 2018, 13:22 от ViTech » Записан

Пока сам не сделаешь...
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.143 секунд. Запросов: 23.