#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)
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)
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
Dernière modification par alx (Le 13/03/2014, à 18:33)