IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Cosinus en c


Sujet :

C

  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 1
    Par défaut Cosinus en c
    Bonjour,
    Je réalise un programme pour calculer la trajectoire d'une bille. Jusqu'ici le programme marche parfaitement, mais quand j'intègre les cosinus et les tangentes au calcul de l'ordonnée de la bille, la fenetre ce referme immédiatement et renvoie 3... Y a-t-il quelque chose de spécial a faire pour la trigo?

    Voici mes déclarations des variables de calcul et mon code d'affichage du point.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    int continuer = 1, continuerD = 1, sourisX, sourisY, tempsActuel = 0, tempsPrecedent = 0, tempsDepart = 0, X = 12, Y = 472;
     
    double distance, gravite = 9.81, vitesse = sqrt(3*9.81), angle = 0, angleRad = 0, Sin2Teta = 0, Teta2 = 0 ,Z = 472, A = 12;
     
                   if(event.button.x >= 745 && event.button.y >= 510 && event.button.x <= 793 && event.button.y <= 558)
                    {
                        tempsDepart = SDL_GetTicks();
                        while(tempsActuel - tempsDepart < 10000)
                        {
                            tempsActuel = SDL_GetTicks();
                            if (tempsActuel - tempsPrecedent > 100)
                            {
                                Sin2Teta=(distance*gravite)/(vitesse*vitesse);
                                Teta2=asin(Sin2Teta);
                                angleRad=Teta2/2;
                                angle = (180*angleRad)/M_PI;
                                X++;
                                Z =  Z - ( - gravite / (2 * pow(vitesse, 2) * pow(cos(angleRad), 2)) * X * X + tan(angleRad) * X);
                                Y = (int)Z;
     
                                positionBille.x = X;
                                positionBille.y = Y;
                                tempsPrecedent = tempsActuel;
                                SDL_BlitSurface(bille, NULL, ecran, &positionBille);
                                SDL_Flip(ecran);
                            }
                        }
                    }

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Salut
    Tu devrais rajouter du printf() pour être sûr que ça vient bien de ces fonctions. Et aussi pour vérifier si le dénominateur de ta division ne vaut pas 0. Et j'espère aussi que tu as inclus <math.h>...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pour utiliser les fonctions cosinus, tangente et sinus, on nous conseille de ne pas utiliser ces fonctions.

    Mais plutôt de créer un tableau puis de lire dedans cosinus[x] pour cos(x), ce qui est d'après mes sources plus rapide.

    Sinon, return 3, c'est un SEGFAULT, tu touches un espace mémoire qui ne t'appartient pas.

    Dans le cas d'une division par 0, c'est un autre type d'erreur.

    Essaye surtout de regarder au niveau de tes pointeurs

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 150
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    Mais plutôt de créer un tableau puis de lire dedans cosinus[x] pour cos(x), ce qui est d'après mes sources plus rapide.
    , oui, sur Amiga ou les consoles portables qui n'ont pas de gestion de virgule flottante. Mais en général, maintenant, les PCs sont capable de répondre en un temps appréciable aux fonctions cos() / sin() (même s'il est vrai que le précalcul sera toujours plus rapide).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Mais plutôt de créer un tableau puis de lire dedans cosinus[x] pour cos(x), ce qui est d'après mes sources plus rapide.
    Pas évident car comment affuter ce tableau ? De 1 en 1 ? De 0.1 en 0.1 ?? De 0.01 en 0.01 ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    C'est à lui de le déterminer en fonction de son utilisation.

    Après comme cela je ne peux évidemment pas donner de chiffres.

    Vu que pour la gravité, il prend 9,81 je dirais qu'il devrait affuter de 0,001 en 0,001 (comme ça il est sûr d'avoir une précision qui lui convienne mais de 0,01 en 0,01 pourrait marcher aussi)

  7. #7
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut
    salut !
    le cosinus ne peut pas engendrer d'erreur ! par contre la tangente, l'arc sinus oui.

    A+

  8. #8
    screetch
    Invité(e)
    Par défaut
    c'est n'importe quoi le cosinus en table qui va plus vite que la fonction cos()

    il y a 25 ans les processeurs etaient lent, stocker les résultats en mémoire ca valait le coup
    depuis les processeurs sont environ 1 000 000 fois plus rapides alors que la mémoire est 1000 fois plus rapide, le processeur mange du cosinus d'arctangeante au petit dej.

    au pire pour des résultats locaux, si tu dois calculer des cosinus pour 5/6 valeurs et les reutiliser, tu fais un cache local.

  9. #9
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pas d'accord sur cette remarque : Je pense qu'un accès à un tableau reste plus rapide que le calcul d'un cosinus. L'intérêt dépend du nombre de cosinus à calculer dans le programme. Si on en a une centaine, peu importe mais pour 1 ou 10 milliards ... Il faut s'adapter à chaque cas particulier.

    Le fait que les processeurs sont 1 000 000 de fois plus rapide qu'avant n'est pas un argument sur le fait qu'on peut négliger les temps de calcul; on demande maintenant à ces processeurs de faire 1 000 000 de fois plus de choses qu'avant.

  10. #10
    screetch
    Invité(e)
    Par défaut
    tu penses ou tu es sur?
    moi je suis sur que non
    la mémoire marche de maniere tres compliquée (et un processeur aussi) et les accès mémoire sont la cause numéro 1 des ralentissements. A cause des latences, des caches, de la coherence...
    a coté de ca maintenant, calculer un cosinus c'est fait sur la FPU ou sur le SSE et ca prend rien comme temps.

    Alors si tu veux faire du code cradoc et foutre en l'air une ligne de cache a chaque fois que tu veux un cosinus, libre a toi; tu vas te retrouver avec deux "cache miss" (un pour le cosinus et un pour celui qui se servait de ce cache) qui sont très lent et comme tu accèdes a la mémoire, tu risques de foutre en l'air des optims du processeur.

    Les solutions les plus simples sont parfois les meilleures hein.

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Il y a deux méthodes :

    Le calcul ou le pré-calcul.
    On ne peut pas dire que l'un d'entre eux est inutile sans connaître l'utilisation qu'on fera de ces valeurs ainsi que les moyens techniques du client.

    Je ne suis pas super-calé dans ce domaine, je ne faisais que dire que j'ai déjà vu qu'on conseillait plutôt un pré-calcul mais mes sources peuvent dater, je l'admet.

    Ensuite tu parles d'accès mémoire, mais de quelle mémoire parles-tu?
    Mémoire Vive? Mémoire Morte?

    Que je sache, une fois le cosinus calculé, il va mettre le résultat dans la mémoire vive.
    Avec le pré-calcul, le résultat est en mémoire vive dès le chargement.
    Bien sûr, on peut décider de calculer les valeurs des cosinus dès le début du lancement pour avoir du pré-calcul par la suite

    Mais on ne peut pas juger de la meilleur méthode sans savoir l'utilisation qu'on va en faire.

  12. #12
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Mémoire Vive? Mémoire Morte?
    La mémoire vive est certes une mémoire "rapide". Mais à l'échelle du processeur, encore un peut lente. Le processeur dispose donc à "côté de lui" de mémoires tampon (caches), et enfin de registres.
    Sans parler du cas extrême où tu demandes une zone mémoire qui a été mise de côté (en mémoire morte selon tes termes) par l'os.

    Une donnée que tu crois en "mémoire vive" peut donc passer de la "mémoire morte" au cache puis atteindre enfin un registre avant d'être utilisée. Ce voyage prend un certain temps (variable selon si la donnée est déjà ou pas dans le registre/cache/mémoire, et selon si elle peut être modifiée par ailleurs que par le proc, et j'en oublie certainement d'autre)

    screetch parle de ce genre de temps je pense.


    J'oubliais aussi un truc, si on utilise des flottants pour représenter les nombres, l'index du tableau devra quand même être un entier, donc il faudra transformer un flottant en entier. Et c'est une instruction de plus.

  13. #13
    screetch
    Invité(e)
    Par défaut
    Certes si tout tient dans le cache, si aucune autre utilisation n'est faite de la mémoire alors ca peut valoir le coup (?) de faire ca.
    Dans n'importe quel programme ca serait un coût plus qu'un gain, a moins de faire du batch de cosinus a longueur de programme.

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    dans ce débat la question est surtout

    Citation Envoyé par Neckara Voir le message
    Pour utiliser les fonctions cosinus, tangente et sinus, on nous conseille de ne pas utiliser ces fonctions.
    Qui te conseille ça et pourquoi ?

    Dans 99.999999999% des cas aujourdhui cela n'a pas d'influence...

    Franchement j'aimerais bien connaître les raisons et le contexte d'un tel conseil !!!

  15. #15
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut urban legend
    on nous conseille de ne pas utiliser ces fonctions.
    les légendes ont la vie dure ...

    A+

  16. #16
    Membre éprouvé
    Homme Profil pro
    Retraité MO
    Inscrit en
    Mai 2008
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité MO
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2008
    Messages : 75
    Par défaut
    J'avais fait un truc comme ça en Basic il y a plus de 20 ans, car je n'avais pas les fonctions trigo dans ma machine.
    J'ai retrouvé un vieux texte dans mes archives. Mais je ne sais plus si c'était un brouillon ou un truc en état de marche. D'ailleurs, j'ai deux définitions du COS, et il me semble me rappeler que l'ATN fonctionnait une fois sur deux.

    Donc c'est à revérifier et réécrire.


    Pi.......................................3.1415926535897932384626433
    COS(radians)........................SIN(radians + (Pi / 2) )
    TAN(radians)........................SIN(radians) / COS(radians)
    COT(radians)........................1 / TAN(radians)


    ____



    function FACTOR(INIFACT) // Factorielle(nombre)

    RESUFACT := INIFACT
    for BASFACT = (INIFACT-1) to 1 step -1
    RESUFACT *= BASFACT
    next

    return RESUFACT

    function SIN(INISINUS) // Sinus(radians)

    IN2SINUS := INISINUS % (2 * Pi)
    RESUSINUS := IN2SINUS
    RESUSINUS -= ( IN2SINUS **3 ) / FACTOR(3 )
    RESUSINUS += ( IN2SINUS **5 ) / FACTOR(5 )
    RESUSINUS -= ( IN2SINUS **7 ) / FACTOR(7 )
    RESUSINUS += ( IN2SINUS **9 ) / FACTOR(9 )
    RESUSINUS -= ( IN2SINUS **11) / FACTOR(11)
    RESUSINUS += ( IN2SINUS **13) / FACTOR(13)
    RESUSINUS -= ( IN2SINUS **15) / FACTOR(15)
    RESUSINUS += ( IN2SINUS **17) / FACTOR(17)
    RESUSINUS -= ( IN2SINUS **19) / FACTOR(19)

    return RESUSINUS

    function COS(INICOSIN)

    IN2SINUS := INICOSIN % (2 * Pi)
    RESUSINUS := 1
    RESUSINUS -= ( IN2SINUS **2 ) / FACTOR(2 )
    RESUSINUS += ( IN2SINUS **4 ) / FACTOR(4 )
    RESUSINUS -= ( IN2SINUS **6 ) / FACTOR(6 )
    RESUSINUS += ( IN2SINUS **8 ) / FACTOR(8 )
    RESUSINUS -= ( IN2SINUS **10) / FACTOR(10)
    RESUSINUS += ( IN2SINUS **12) / FACTOR(12)
    RESUSINUS -= ( IN2SINUS **14) / FACTOR(14)
    RESUSINUS += ( IN2SINUS **16) / FACTOR(16)
    RESUSINUS -= ( IN2SINUS **18) / FACTOR(18)

    return RESUSINUS

    function ATN(INIARCTN) // ArcTAN(tang) => rad

    if INIARCTN < 10 .and. INIARCTN > -10
    RESUARCTN := Pi * 1.5
    TPNARCTN := RESUARCTN / 20
    do while abs(TAN(RESUARCTN) - INIARCTN) > 0.00001
    do while TAN(RESUARCTN) > INIARCTN
    RESUARCTN -= TPNARCTN
    enddo
    do while TAN(RESUARCTN) < INIARCTN
    RESUARCTN += TPNARCTN
    enddo
    TPNARCTN *= 0.1
    enddo
    elseif INIARCTN < -10000
    RESUARCTN := (2 * Pi * 90.02 / 360)
    elseif INIARCTN < -1000
    RESUARCTN := (2 * Pi * 90.3 / 360)
    elseif INIARCTN < -100
    RESUARCTN := (2 * Pi * 92 / 360)
    elseif INIARCTN < 100
    RESUARCTN := (2 * Pi * 88 / 360)
    elseif INIARCTN < 1000
    RESUARCTN := (2 * Pi * 89.7 / 360)
    else
    RESUARCTN := (2 * Pi * 89.98 / 360)
    endif
    // if RESUARCTN > Pi ; RESUARCTN -= Pi ; endif

    return (RESUARCTN - Pi)


    PS : et en plus je n'ai jamais été un as en maths !

  17. #17
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut
    salut !

    je viens aussi de cette époque ;=)
    le basic utilisé était assez extraordinaire (je pense desassemblé du HP-65 car même bug sur les sqrt d'un float < 1e-9) ...

    A+

  18. #18
    Membre éclairé Avatar de aslo92
    Homme Profil pro
    Ingénieur développement logiciels temps réel
    Inscrit en
    Février 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels temps réel
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2012
    Messages : 43
    Par défaut
    c'est n'importe quoi le cosinus en table qui va plus vite que la fonction cos()
    J'ai chronométré les 2 méthodes sur un PC récent (processeur i5-2400 à 3.1GHz avec 4 Go de Ram)

    Voici les résultats de la lecture de 10 valeurs de cosinus avec une précision de 0.0001 rad

    opération: a = cos(angle) ==> nombre de coups d'horloge cpu = 2220
    opération: a = cos_t[(int)(angle * 10000)] ==> nombre de coups d'horloge cpu = 329

  19. #19
    screetch
    Invité(e)
    Par défaut
    faudrait voir comment tu viens de foutre en l'air ton cache pour toute les opérations suivantes maintenant. Même si le cosinus lui même est plus long a calculer, si ta table de cosinus n'était pas déjà dans le cache (ce qui ne se voit pas sur un benchmark) ou si tu viens de decharger une ligne de cache qui aurait été utile deux instructions plus bas (ce qu'un benchmark ne permet pas de mesurer non plus) alors au final tu y perds.

  20. #20
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    C'est surtout qu'avant d'en arriver à tenter d'optimiser des opératons de base, il vaudrait mieux passer son temps à optimiser l'alogorithme qui les utilise... Plus l'écriture du code...

    Une fois cela fait, et si ça n'est pas encoe suffisant, on peut éventuellement penser à se compliquer la vie..

    Mais c'est tout à fait inutile dans 99.999999999999 % des cas...

Discussions similaires

  1. tracer un joli cosinus
    Par max2x dans le forum Delphi
    Réponses: 8
    Dernier message: 21/03/2007, 19h28
  2. sinus -1 cosinus -1 [Math]
    Par Extra-Nitro dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 10/01/2007, 14h14
  3. Formule linéaire de calcul de cosinus
    Par méphistopheles dans le forum Algorithmes et structures de données
    Réponses: 16
    Dernier message: 21/12/2005, 18h47
  4. Arc cosinus
    Par SuperCed dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 17/02/2005, 17h58
  5. cosinus complexe
    Par Mat 74 dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 26/01/2005, 10h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo