Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 13/03/2014, à 13:22

Compte anonymisé

[bug libm] bug cos/sin de la librairie math (libc6)

EDIT2:
Bug corrigé avec la dernière mise à jour de libc6.

EDIT:
Le bug est confirmé dans la librairie : https://sourceware.org/bugzilla/show_bug.cgi?id=16623
Pas de correction pour le moment dans eglibc 2.19 (mais corrigé dans glibc).

Bonjour à tous,

Ceci ne concerne que Trusty.
Je me suis rendu compte que la librairie C mathématique (libm) donne des résultats faux de cosinus/sinus pour des valeurs importantes de l'angle.
La version de eglibc (qui contient libc6 et libm) dans trusty est la 2.19 sortie en février 2014. Sur debian unstable et experimental, ils sont toujours en version 2.18.
Exemple de calculs faux :

sin(2*pi*0.27*7390843)   =  -0.63742399  OK
sin(2*pi*2.27*7390843)   =   0.63742398  KO

cos(2*pi*0.27*7390879)   =  -0.48175367  OK
cos(2*pi*2.27*7390879)   =   0.48175367  KO

A chaque fois l'angle différe d'un nombre entier élevé de multiple de 2*pi. Mais les résultats devraient être identiques !
Voici un code C qui permet de tester le bug (bug_libc6_cos.c) :

/*
 * Bug cos() & sin() dans libc6 (libm) ubuntu 14.04
 * C'est un bug de la version 2.19 de eglibc (qui contient libc6 et libm)
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define PRECISION   1e-5

void bug_cos(void)
{
  int        n;
  double     c1,c2,s1,s2;
  int        nerr  = 0;

  for (n = 0; n < 10000000; n++)
  {

    /* si pas d'erreur c1 = c2 et s1 = s2 */
    c1 = cos(2. * M_PI * 0.27 * (double) n);
    c2 = cos(2. * M_PI * 2.27 * (double) n);
    s1 = sin(2. * M_PI * 0.27 * (double) n);
    s2 = sin(2. * M_PI * 2.27 * (double) n);

    /* si |c2 - c1| > PRECISION */
    if (fabs(c2-c1) > PRECISION)
    {
      fprintf(stdout,
          "ERR:\n"
          "      cos(2*pi*0.27*%d)         = %12.8f  OK\n"
          "      cos(2*pi*2.27*%d)         = %12.8f  KO\n",
          n,c1,n,c2);

      nerr++;
    }

    /* si |s2 - s1| > PRECISION */
    if (fabs(s2-s1) > PRECISION)
    {
      fprintf(stdout,
          "ERR:\n"
          "      sin(2*pi*0.27*%d)         = %12.8f  OK\n"
          "      sin(2*pi*2.27*%d)         = %12.8f  KO\n",
          n,s1,n,s2);

      nerr++;
    }

    /* n'affiche que les premieres erreurs ... */
    if (nerr > 4)
    {
      fprintf(stdout,"ERR : ...\n\n");
      break;
    }

  }
}

int main(int na, char *arg[])
{
  bug_cos();

  return 0;
}

Pour compiler : gcc -O2 -Wall bug_libc6_cos.c -o bug_libc6_cos -lm

La libm est utilisée par un tas de logiciels : audacity, octave, matlab ou la calculette gnome. Ils sont donc soumis au même bug. Comme ce bug n'intervient que pour des angles importants (> 10e8 radians) ça limite sa nuisance !

Dernière modification par alx (Le 25/03/2014, à 21:14)

#2 Le 13/03/2014, à 15:27

moko138

Re : [bug libm] bug cos/sin de la librairie math (libc6)

alx a écrit :

Exemple de calculs faux :

sin(2*pi*0.27*7390843)   =  -0.63742399  OK
sin(2*pi*2.27*7390843)   =   0.63742398  KO

cos(2*pi*0.27*7390879)   =  -0.48175367  OK
cos(2*pi*2.27*7390879)   =   0.48175367  KO

A chaque fois l'angle différe dans nombre entier élevé de multiple de 2*pi.

"dans" ?
  Si tu as voulu dire "d'un" (nombre entier élevé de multiple de 2*pi), et si je comprends bien - ce qui n'est pas sûr - ta notation,
A = [2*pi*0.27*7390843]  =  [2*pi*7390843*0.27]
tandis que
B = [2*pi*2.27*7390843]  =  [2*pi*7390843*(0.27 + 2)]
                                         =  [2*pi*7390843*0.27]  +  [2*pi*7390843]*2
                                         =  A  +                                2*pi*(7390843*2)

Donc B-A = 2*pi*(7390843*2)
Donc B    = A + n*2*pi, (où n est "élevé")
Donc sin(B) = sin(A). Mais, dis-tu, ce n'est pas ce que donne libm dans Trusty.

1)  Bravo d'avoir levé ce lièvre !

2)  Pourquoi un script de vérification ? Je n'ai pas compris.

3)   Mais comme tu expliques que libm est une dépendance d'audacity, grâce à toi, je comprends enfin les compositions de Stockhausen ! Elles reposent sur la libm de Trusty !
Merci !


%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel :  À la découverte de dcraw

Hors ligne

#3 Le 13/03/2014, à 16:38

Compte anonymisé

Re : [bug libm] bug cos/sin de la librairie math (libc6)

dans -> d'un : corrigé dans le 1er post.

Oui les 2 angles diffèrent de 2*pi*n avec n très grand.

Le code C est pour les gens que ça intéresse. Il cherche à partir de quel 'n' ça bug (ou pas).

Extrait du paquet libc6 qui contient libm :

Description: Embedded GNU C Library: Shared libraries
Contains the standard libraries that are used by nearly all programs on
the system. This package includes shared versions of the standard C library
and the standard math library, as well as many others.

Tout programme qui fait des opérations matématiques (cos, sin, exp, log, sqrt, pow ...) utilise libm.
Rien que dans mon /usr/bin, j'ai 500 executables qui chargent (et utilisent surement) la librairie libm.so.

#4 Le 13/03/2014, à 17:27

moko138

Re : [bug libm] bug cos/sin de la librairie math (libc6)

alx a écrit :

Le code C est pour les gens que ça intéresse. Il cherche à partir de quel 'n' ça bug (ou pas).

  D'aaaaaccord !

  Et pour Stockhausen, que va-t-on entendre, avec une libm correcte ?...
Ça me rappelle une plaisante histoire, celle du compositeur moscovite, disons en 1950, à qui un camarade commissaire assène :
  "elle est bien ta musique, camarade ! Mais... pas assez réaliste socialiste, tu sais !"

  Tu connais la suite ?


%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel :  À la découverte de dcraw

Hors ligne

#5 Le 13/03/2014, à 18:33

Compte anonymisé

Re : [bug libm] bug cos/sin de la librairie math (libc6)

Tu entendras correctement l'hélicoptère du coup.
libm n'a que faire du socialisme stalinien tongue

Dernière modification par alx (Le 13/03/2014, à 18:33)