BG Development


  Reply to this topicStart new topicStart Poll

> C++ Необяснима разлика в резултата на програмата, Два варианта на формула
Д.Русинов
Публикувано на: 19-10-2022, 18:08
Quote Post



Име: Димитър Русинов
Група: Потребител
Ранг: Новопостъпил

Мнения: 2
Регистриран на: 19.10.22



Проста формула въведена по два равностойни начина дава различни резултати само за определени входни променливи n=15,21,22,37 (Примерно н=15 x=8 y=7).

b=pow(x,2)-pow(y,2) или b=x*x - y*y

Прикачен файл ( Брой сваляния: 7 )
Прикачен файл  Problem_masiv.cpp
PMEmail Poster
Top
logi
Публикувано на: 19-10-2022, 18:34
Quote Post



Име: Свилен Стоянов
Група: Потребител
Ранг: Посетител

Мнения: 85
Регистриран на: 27.08.05



pow работи с плаваща запетая (double), в даден момент е възможно да имаш 48.9999999999 вместо 49 и когато го върнеш в цяло (int) ще получиш 48.


--------------------
PMUsers WebsiteICQ
Top
Bender++
Публикувано на: 19-10-2022, 19:30
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 349
Регистриран на: 18.04.21



това е един от проблемите, които ръст решава icon_smile.gif


--------------------
Ваксините са лъжа и НЕ работят! Не на ковид фашизма!
Слава на Цар Путин! Долу украинските фашисти!
Слава на героите - Z V
PMEmail Poster
Top
ici
Публикувано на: 19-10-2022, 23:02
Quote Post


Group Icon
Име: Ивайло Илчев
Група: VIP
Ранг: Почетен член

Мнения: 17960
Регистриран на: 06.06.04



С GCC 11.2/MSYS2 няма разлика.
CODE

#include<iostream>
#include<cmath>

using namespace std;

int main()
{
 int n,x,y, a, b, ctr;
 const int X[]={2,3,4,4,5,5,6,6,7,7,7,8,8,8,8,9,9,9,10,10,10,10,11,11,11,11,12,12,12,13,13,13,13,14,14,14,14,15,15,15,16,16,16,16,16,17,17,17,17,18,18,18,19,19,19,19,20,20,20,20};
 const int Y[]={1,2,1,3,2,4,1,5,2,4,6,1,3,5,7,2,4,8, 1, 3, 7, 9, 2, 4, 6, 8, 1 ,5, 7, 2, 4, 6, 8, 1, 3, 5, 9 ,2, 4, 8, 1, 3, 5, 7, 9, 2, 4, 6, 8, 1, 5, 7, 2 ,4, 6, 8, 1, 3 ,7, 9};

 cout << "_____________________________________________________________________"  <<  endl;
 for (ctr=0; ctr < min((sizeof(X) / sizeof(int)), (sizeof(Y) / sizeof(int))); ctr++)
 {
            x=X[ctr];
            y=Y[ctr];
                        
            a = pow(x,2) - pow(y,2);
                          
            b = x*x - y*y;
            cout << ctr << ':' << x << ',' << y << " = " << a << ',' << b << '|' << a- b << endl;
      }
      cout << "_____________________________________________________________________"  <<  endl;
 
  return(0);
}  



Прикачена картинка (Кликнете на картинката, за да я увеличите!)
Прикачена картинка


--------------------
Ние не сме в една лодка, ние сме в една буря. Лодките са различни.

Следващият път когато се почувстваш ненужен, грозен и недооценен, помни че освен това си и тъп.
PMEmail PosterUsers Website
Top
Дон Реба
Публикувано на: 28-10-2022, 10:35
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 9748
Регистриран на: 11.11.06



pow минава през логаритъм и експонента, което задължително губи точност. винаги е по-добре да се ползва х*х вместо pow(x,2)
PM
Top
Дон Реба
Публикувано на: 28-10-2022, 10:45
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 9748
Регистриран на: 11.11.06



QUOTE (ici @ 19-10-2022, 23:02)
С GCC 11.2/MSYS2 няма разлика.

... в отпечатаното няма icon_smile.gif
PM
Top
Bender++
Публикувано на: 28-10-2022, 18:45
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 349
Регистриран на: 18.04.21



QUOTE (Дон Реба @ 28-10-2022, 10:35)
pow минава през логаритъм и експонента,  което задължително губи точност. винаги е по-добре да се ползва х*х вместо pow(x,2)

в ръст се оптимизира и LLVM изкарва еднакъв код и за двете, така че би трябвало и в ц++ да е същото

Това мнение е било редактирано от Bender++ на 28-10-2022, 18:46


--------------------
Ваксините са лъжа и НЕ работят! Не на ковид фашизма!
Слава на Цар Путин! Долу украинските фашисти!
Слава на героите - Z V
PMEmail Poster
Top
ici
Публикувано на: 28-10-2022, 19:57
Quote Post


Group Icon
Име: Ивайло Илчев
Група: VIP
Ранг: Почетен член

Мнения: 17960
Регистриран на: 06.06.04



QUOTE (Дон Реба @ 28-10-2022, 11:35)
pow минава през логаритъм и експонента, което задължително губи точност. винаги е по-добре да се ползва х*х вместо pow(x,2)

Степенуването е много тежка операция. Аз имах алгоритъм за инфрачервени термометри, като приложните инженери бяха вкарали формулата за корекция както си се пише (x ^ 4 * N) - 4. Като замених във формулата със умножение и два квадратни корена, всичко стана шест пъти по-бързо.


--------------------
Ние не сме в една лодка, ние сме в една буря. Лодките са различни.

Следващият път когато се почувстваш ненужен, грозен и недооценен, помни че освен това си и тъп.
PMEmail PosterUsers Website
Top
Дон Реба
Публикувано на: 30-10-2022, 11:01
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 9748
Регистриран на: 11.11.06



QUOTE (ici @ 28-10-2022, 19:57)
QUOTE (Дон Реба @ 28-10-2022, 11:35)
pow минава през логаритъм и експонента,  което задължително губи точност. винаги е по-добре да се ползва х*х вместо pow(x,2)

Степенуването е много тежка операция. Аз имах алгоритъм за инфрачервени термометри, като приложните инженери бяха вкарали формулата за корекция както си се пише (x ^ 4 * N) - 4. Като замених във формулата със умножение и два квадратни корена, всичко стана шест пъти по-бързо.

така е, това е една от малкото операции които все още има смисъл да се оптимизират
PM
Top
Дон Реба
Публикувано на: 30-10-2022, 11:24
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 9748
Регистриран на: 11.11.06



QUOTE (Bender++ @ 28-10-2022, 18:45)
QUOTE (Дон Реба @ 28-10-2022, 10:35)
pow минава през логаритъм и експонента,  което задължително губи точност. винаги е по-добре да се ползва х*х вместо pow(x,2)

в ръст се оптимизира и LLVM изкарва еднакъв код и за двете, така че би трябвало и в ц++ да е същото

powf не се оптимизира изобщо, вика си го направо
pow се "оптимизира", ама е някво лайняно, какви са тия магии с je и ноповете не е ясно, но е явно някакъв "талаш" от оптимизацията

CODE

      LOG::Write("%f\n",pow(mg.sets.bumpmul,2));      
000000013F99AE84  movss       xmm0,dword ptr [mg+5Ch (13FC45BBCh)]
000000013F99AE8C  movss       xmm1,dword ptr [__real@3f800000 (13FB21FF0h)]
000000013F99AE94  mov         eax,2
000000013F99AE99  nop         dword ptr [rax]
000000013F99AEA0  test        al,1
000000013F99AEA2  je          CbrdfApp::OnTst+28h (13F99AEA8h)
000000013F99AEA4  mulss       xmm1,xmm0
000000013F99AEA8  shr         eax,1
000000013F99AEAA  je          CbrdfApp::OnTst+32h (13F99AEB2h)
000000013F99AEAC  mulss       xmm0,xmm0
000000013F99AEB0  jmp         CbrdfApp::OnTst+20h (13F99AEA0h)
000000013F99AEB2  unpcklps    xmm1,xmm1
000000013F99AEB5  lea         rcx,[string "%f\n" (13FB34584h)]
000000013F99AEBC  cvtps2pd    xmm1,xmm1
000000013F99AEBF  movd        rdx,xmm1
000000013F99AEC4  call        LOG::Write (13F965EB0h)


а ето как трябва да бъде, същото нещо но с експлицитна инлайн функция или пряко умножение ( еднакви са)
CODE

      LOG::Write("%f\n",sqr(mg.sets.bumpmul));      
000000013F97B314  movss       xmm0,dword ptr [mg+5Ch (13FC25BBCh)]
000000013F97B31C  lea         rcx,[string "%f\n" (13FB145C4h)]
000000013F97B323  mulss       xmm0,xmm0
000000013F97B327  unpcklps    xmm0,xmm0
000000013F97B32A  cvtps2pd    xmm1,xmm0
000000013F97B32D  movd        rdx,xmm1
000000013F97B332  call        LOG::Write (13F945E20h)


като цяло НЕ Е добре да се оптимизира , защото оптимизацията не бива да променя бинарния вид на резултата. е, има един флаг на компилатора който точно това определя - дали се позволяват оптимизации които са математически верни, но не и бинарно тъждествени. по-добре да не се пускат такива оптимизации
PM
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0