J'ai un syst=E8me qui me donne des informations suivant un temps en
secondes (au format double) dont je ne ma=EEtrise pas la fr=E9quence.
Je veux n'afficher ces informations que toutes les 10 secondes.
Cela revient donc =E0 faire un test pour savoir si le temps courant est
un multiple de 10.
Le code de test ci-dessous m'a l'air de fonctionner.
Maintenant, est-ce la bonne m=E9thode ?
Peux-t-on faire mieux ?
#include <math.h>
#include <stdio.h>
int main(void)
{
int i =3D 0;
int n =3D 36001;
double step =3D 0.1;
double seconds =3D 0.0;
for (; i<n; i++)
{
double sf; /* floored seconds */
double sc; /* ceiled seconds */
double sd; /* seconds that must be displayed */
double discr =3D 10.0;
double precision =3D 1e-3;
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Alain Montfranc
Fane a écrit
Bonjour,
J'ai un système qui me donne des informations suivant un temps en secondes (au format double) dont je ne maîtrise pas la fréquence. Je veux n'afficher ces informations que toutes les 10 secondes. Cela revient donc à faire un test pour savoir si le temps courant est un multiple de 10.
Le code de test ci-dessous m'a l'air de fonctionner. Maintenant, est-ce la bonne méthode ? Peux-t-on faire mieux ?
#include <math.h> #include <stdio.h>
int main(void) { int i = 0; int n = 36001; double step = 0.1; double seconds = 0.0;
for (; i<n; i++) { double sf; /* floored seconds */ double sc; /* ceiled seconds */ double sd; /* seconds that must be displayed */ double discr = 10.0; double precision = 1e-3;
je ferais plutot un truc plus simple : - avoir une variabl "last" qui contient le timestamp du dernier affichage - si (timestamp courant) >= (last + 10.0) => afficher et mettre a jour last
Fane a écrit
Bonjour,
J'ai un système qui me donne des informations suivant un temps en
secondes (au format double) dont je ne maîtrise pas la fréquence.
Je veux n'afficher ces informations que toutes les 10 secondes.
Cela revient donc à faire un test pour savoir si le temps courant est
un multiple de 10.
Le code de test ci-dessous m'a l'air de fonctionner.
Maintenant, est-ce la bonne méthode ?
Peux-t-on faire mieux ?
#include <math.h>
#include <stdio.h>
int main(void)
{
int i = 0;
int n = 36001;
double step = 0.1;
double seconds = 0.0;
for (; i<n; i++)
{
double sf; /* floored seconds */
double sc; /* ceiled seconds */
double sd; /* seconds that must be displayed */
double discr = 10.0;
double precision = 1e-3;
je ferais plutot un truc plus simple :
- avoir une variabl "last" qui contient le timestamp du dernier
affichage
- si (timestamp courant) >= (last + 10.0) => afficher et mettre a jour
last
J'ai un système qui me donne des informations suivant un temps en secondes (au format double) dont je ne maîtrise pas la fréquence. Je veux n'afficher ces informations que toutes les 10 secondes. Cela revient donc à faire un test pour savoir si le temps courant est un multiple de 10.
Le code de test ci-dessous m'a l'air de fonctionner. Maintenant, est-ce la bonne méthode ? Peux-t-on faire mieux ?
#include <math.h> #include <stdio.h>
int main(void) { int i = 0; int n = 36001; double step = 0.1; double seconds = 0.0;
for (; i<n; i++) { double sf; /* floored seconds */ double sc; /* ceiled seconds */ double sd; /* seconds that must be displayed */ double discr = 10.0; double precision = 1e-3;
je ferais plutot un truc plus simple : - avoir une variabl "last" qui contient le timestamp du dernier affichage - si (timestamp courant) >= (last + 10.0) => afficher et mettre a jour last
Antoine Leca
Le 24/02/2009 16:23, Fane écrivit :
J'ai un système qui me donne des informations suivant un temps en secondes (au format double) dont je ne maîtrise pas la fréquence. Je veux n'afficher ces informations que toutes les 10 secondes. Cela revient donc à faire un test pour savoir si le temps courant est un multiple de 10.
Non. Si tu supposes que tu disposes d'une base de temps précise, tu devrais comprendre que tu ne peux pas être sûr de regarder l'horloge EXACTEMENT au moment l'aiguille des minutes est sur un multiple de 10 ET l'aiguille des secondes sur 0 ET l'aiguille des nanosecondes sur 0 ! Déjà dans la pratique, pour te synchroniser avec ta montre à la seconde près, tu vas attendre qu'il soit disons 19:09:50 (environ), et tu vas arrêter de faire quoique que ce soit d'autres jusqu'à ce que l'aiguille des secondes passe sur le 0.
En informatique c'est pareil, lorsque tu approches du moment qui va bien... if( prochain_top-temps_actuel()>10.0 ) va_faire_autre_chose(); tu te concentres... while( temps_actuel()<prochain_top ) fait_juste_un_truc_rapide(); et quand c'est bon tu affiches : affiche(); et on attend le prochain top ! prochain_top += 10.0; /* ou encore prochain_top = temps_actuel()+10.0; */
En réalité les deux tests sont équivalents (donc on peut en supprimer un), mais le comportement n'est pas le même : le premier est un test sur interruption ou polling, le second est une attente active.
Et à part cela, OEQLC?
Antoine
Le 24/02/2009 16:23, Fane <fanou73@free.fr> écrivit :
J'ai un système qui me donne des informations suivant un temps en
secondes (au format double) dont je ne maîtrise pas la fréquence.
Je veux n'afficher ces informations que toutes les 10 secondes.
Cela revient donc à faire un test pour savoir si le temps courant est
un multiple de 10.
Non. Si tu supposes que tu disposes d'une base de temps précise, tu
devrais comprendre que tu ne peux pas être sûr de regarder l'horloge
EXACTEMENT au moment l'aiguille des minutes est sur un multiple de 10 ET
l'aiguille des secondes sur 0 ET l'aiguille des nanosecondes sur 0 !
Déjà dans la pratique, pour te synchroniser avec ta montre à la seconde
près, tu vas attendre qu'il soit disons 19:09:50 (environ), et tu vas
arrêter de faire quoique que ce soit d'autres jusqu'à ce que l'aiguille
des secondes passe sur le 0.
En informatique c'est pareil, lorsque tu approches du moment qui va bien...
if( prochain_top-temps_actuel()>10.0 ) va_faire_autre_chose();
tu te concentres...
while( temps_actuel()<prochain_top )
fait_juste_un_truc_rapide();
et quand c'est bon tu affiches :
affiche();
et on attend le prochain top !
prochain_top += 10.0;
/* ou encore prochain_top = temps_actuel()+10.0; */
En réalité les deux tests sont équivalents (donc on peut en supprimer
un), mais le comportement n'est pas le même : le premier est un test sur
interruption ou polling, le second est une attente active.
J'ai un système qui me donne des informations suivant un temps en secondes (au format double) dont je ne maîtrise pas la fréquence. Je veux n'afficher ces informations que toutes les 10 secondes. Cela revient donc à faire un test pour savoir si le temps courant est un multiple de 10.
Non. Si tu supposes que tu disposes d'une base de temps précise, tu devrais comprendre que tu ne peux pas être sûr de regarder l'horloge EXACTEMENT au moment l'aiguille des minutes est sur un multiple de 10 ET l'aiguille des secondes sur 0 ET l'aiguille des nanosecondes sur 0 ! Déjà dans la pratique, pour te synchroniser avec ta montre à la seconde près, tu vas attendre qu'il soit disons 19:09:50 (environ), et tu vas arrêter de faire quoique que ce soit d'autres jusqu'à ce que l'aiguille des secondes passe sur le 0.
En informatique c'est pareil, lorsque tu approches du moment qui va bien... if( prochain_top-temps_actuel()>10.0 ) va_faire_autre_chose(); tu te concentres... while( temps_actuel()<prochain_top ) fait_juste_un_truc_rapide(); et quand c'est bon tu affiches : affiche(); et on attend le prochain top ! prochain_top += 10.0; /* ou encore prochain_top = temps_actuel()+10.0; */
En réalité les deux tests sont équivalents (donc on peut en supprimer un), mais le comportement n'est pas le même : le premier est un test sur interruption ou polling, le second est une attente active.
Et à part cela, OEQLC?
Antoine
Fane
On 26 fév, 19:25, Antoine Leca wrote:
Le 24/02/2009 16:23, Fane écrivit :
> J'ai un système qui me donne des informations suivant un temps en > secondes (au format double) dont je ne maîtrise pas la fréquence. > Je veux n'afficher ces informations que toutes les 10 secondes. > Cela revient donc à faire un test pour savoir si le temps courant est > un multiple de 10.
Non. Si tu supposes que tu disposes d'une base de temps précise, tu devrais comprendre que tu ne peux pas être sûr de regarder l'horloge EXACTEMENT au moment l'aiguille des minutes est sur un multiple de 10 ET l'aiguille des secondes sur 0 ET l'aiguille des nanosecondes sur 0 ! Déjà dans la pratique, pour te synchroniser avec ta montre à la sec onde près, tu vas attendre qu'il soit disons 19:09:50 (environ), et tu vas arrêter de faire quoique que ce soit d'autres jusqu'à ce que l'aiguil le des secondes passe sur le 0.
Justement, ce n'est pas du tout ce que je veux faire. C'est l'objet du test avec une précision à e-3 dans mon code.
De toute façon, ce n'était surement pas la bonne méthode. Il vaut mieux afficher le premier pas de temps dépassant un multiple de 10.
[...]
Et à part cela, OEQLC?
Ben, je savais faire en java ou en scheme. J'ai tenté un truc en C et je voulais savoir si je pouvais le programmer comme ça. Désolé, si tu penses que c'était HS.
Fane.
On 26 fév, 19:25, Antoine Leca <r...@localhost.invalid> wrote:
Le 24/02/2009 16:23, Fane <fano...@free.fr> écrivit :
> J'ai un système qui me donne des informations suivant un temps en
> secondes (au format double) dont je ne maîtrise pas la fréquence.
> Je veux n'afficher ces informations que toutes les 10 secondes.
> Cela revient donc à faire un test pour savoir si le temps courant est
> un multiple de 10.
Non. Si tu supposes que tu disposes d'une base de temps précise, tu
devrais comprendre que tu ne peux pas être sûr de regarder l'horloge
EXACTEMENT au moment l'aiguille des minutes est sur un multiple de 10 ET
l'aiguille des secondes sur 0 ET l'aiguille des nanosecondes sur 0 !
Déjà dans la pratique, pour te synchroniser avec ta montre à la sec onde
près, tu vas attendre qu'il soit disons 19:09:50 (environ), et tu vas
arrêter de faire quoique que ce soit d'autres jusqu'à ce que l'aiguil le
des secondes passe sur le 0.
Justement, ce n'est pas du tout ce que je veux faire.
C'est l'objet du test avec une précision à e-3 dans mon code.
De toute façon, ce n'était surement pas la bonne méthode.
Il vaut mieux afficher le premier pas de temps dépassant un multiple
de 10.
[...]
Et à part cela, OEQLC?
Ben, je savais faire en java ou en scheme. J'ai tenté un truc en C et
je voulais savoir si je pouvais le programmer comme ça.
Désolé, si tu penses que c'était HS.
> J'ai un système qui me donne des informations suivant un temps en > secondes (au format double) dont je ne maîtrise pas la fréquence. > Je veux n'afficher ces informations que toutes les 10 secondes. > Cela revient donc à faire un test pour savoir si le temps courant est > un multiple de 10.
Non. Si tu supposes que tu disposes d'une base de temps précise, tu devrais comprendre que tu ne peux pas être sûr de regarder l'horloge EXACTEMENT au moment l'aiguille des minutes est sur un multiple de 10 ET l'aiguille des secondes sur 0 ET l'aiguille des nanosecondes sur 0 ! Déjà dans la pratique, pour te synchroniser avec ta montre à la sec onde près, tu vas attendre qu'il soit disons 19:09:50 (environ), et tu vas arrêter de faire quoique que ce soit d'autres jusqu'à ce que l'aiguil le des secondes passe sur le 0.
Justement, ce n'est pas du tout ce que je veux faire. C'est l'objet du test avec une précision à e-3 dans mon code.
De toute façon, ce n'était surement pas la bonne méthode. Il vaut mieux afficher le premier pas de temps dépassant un multiple de 10.
[...]
Et à part cela, OEQLC?
Ben, je savais faire en java ou en scheme. J'ai tenté un truc en C et je voulais savoir si je pouvais le programmer comme ça. Désolé, si tu penses que c'était HS.
Fane.
Antoine Leca
Le 27/02/2009 12:24, Fane écrivit :
Et à part cela, OEQLC?
Ben, je savais faire en java ou en scheme. J'ai tenté un truc en C et je voulais savoir si je pouvais le programmer comme ça. Désolé, si tu penses que c'était HS.
En fait, l'introduction (à propos des horloges et tout cela) de ton premier message a suscité deux réponses sur le mode « il ne faut pas faire comme cela » concernant en fait le piège de faire une opération de comparaison entre une donnée un tant soit peu aléatoire et une constante (le fait que ce soit des float ne rentre pas en ligne de compte, si le temps est mesuré en ms dans un entier et que tu compares à un multiple de 600000 tu as exactement le même souci). Ce problème n'a rien à voir avec le langage C en soit, même si c'est un contexte où on le rencontre facilement à cause de l'utilisation des float en C, d'où les réponses « automatiques ».
En fait ta vraie question était, comment faire en C une opération sur des flottants. Et évidemment, ce n'est absolument pas hors sujet sur ce groupe, c'est seulement inutile dans le contexte annoncé ;-).
: Cela revient donc à faire un test pour savoir si le temps courant est : un multiple de 10. : : Le code de test ci-dessous m'a l'air de fonctionner. : Maintenant, est-ce la bonne méthode ? : Peux-t-on faire mieux ?
Je ne sais pas si c'est mieux (il faudrait déjà définir l'échelle de jugement pour ce faire), mais je trouve cela un peu compliqué.
Savoir si une valeur double V est un multiple de X : int est_multiple(double v, double x) { return !fmod(v,x); }
Évidemment, codé aussi bêtement, cela ne va pas marcher pour des problèmes d'arrondis. Si V est légèrement supérieur à nX, donc si le résultat de fmod est inférieur à l'epsilon E, cela vaut aussi ; d'où int est_presque_multiple(double v, double x, double e) { return fmod(v,x) < e; }
Mais bien sûr, le problème existe aussi si V est légèrement inférieur... ce qui revient à dire que V+E soit légèrement supérieur à nX, d'où int est_proche_multiple(double v, double x, double e) { return fmod(v+e,x) < e*2.0; }
[ Régler les cas où V, X ou E sont négatifs ou nuls est laissé à l'appréciation du lecteur ; pour ma part j'estime que cela alourdira notablement le code sans avoir un intérêt pratique exceptionnel. ]
Avec l'environnement de test que tu avais mis (et en supposant le générateur de nombres aléatoires proposé par la norme), cela donne
int main(void) { int i = 0, j = 0; int n = 50000; double step = 0.1/23456.0; double seconds = 0.0; double ref[] {0,0,260,300,310,330,510,850,1020,1050,2280,2490,3390,-1};
if ( est_proche_multiple(seconds, discr, precision) ) { printf("secondes=%-12ft affiché à %gn", seconds, floor(seconds+.5) ); if( ref[j]==floor(seconds+.5) ) ++j; }
seconds += step*rand(); }
return j= ? 0 : EXIT_FAILURE; }
Antoine
Le 27/02/2009 12:24, Fane écrivit :
Et à part cela, OEQLC?
Ben, je savais faire en java ou en scheme. J'ai tenté un truc en C et
je voulais savoir si je pouvais le programmer comme ça.
Désolé, si tu penses que c'était HS.
En fait, l'introduction (à propos des horloges et tout cela) de ton
premier message a suscité deux réponses sur le mode « il ne faut pas
faire comme cela » concernant en fait le piège de faire une opération de
comparaison entre une donnée un tant soit peu aléatoire et une constante
(le fait que ce soit des float ne rentre pas en ligne de compte, si le
temps est mesuré en ms dans un entier et que tu compares à un multiple
de 600000 tu as exactement le même souci). Ce problème n'a rien à voir
avec le langage C en soit, même si c'est un contexte où on le rencontre
facilement à cause de l'utilisation des float en C, d'où les réponses «
automatiques ».
En fait ta vraie question était, comment faire en C une opération sur
des flottants. Et évidemment, ce n'est absolument pas hors sujet sur ce
groupe, c'est seulement inutile dans le contexte annoncé ;-).
: Cela revient donc à faire un test pour savoir si le temps courant est
: un multiple de 10.
:
: Le code de test ci-dessous m'a l'air de fonctionner.
: Maintenant, est-ce la bonne méthode ?
: Peux-t-on faire mieux ?
Je ne sais pas si c'est mieux (il faudrait déjà définir l'échelle de
jugement pour ce faire), mais je trouve cela un peu compliqué.
Savoir si une valeur double V est un multiple de X :
int est_multiple(double v, double x) {
return !fmod(v,x);
}
Évidemment, codé aussi bêtement, cela ne va pas marcher pour des
problèmes d'arrondis. Si V est légèrement supérieur à nX, donc si le
résultat de fmod est inférieur à l'epsilon E, cela vaut aussi ; d'où
int est_presque_multiple(double v, double x, double e) {
return fmod(v,x) < e;
}
Mais bien sûr, le problème existe aussi si V est légèrement inférieur...
ce qui revient à dire que V+E soit légèrement supérieur à nX, d'où
int est_proche_multiple(double v, double x, double e) {
return fmod(v+e,x) < e*2.0;
}
[ Régler les cas où V, X ou E sont négatifs ou nuls est laissé à
l'appréciation du lecteur ; pour ma part j'estime que cela alourdira
notablement le code sans avoir un intérêt pratique exceptionnel. ]
Avec l'environnement de test que tu avais mis (et en supposant le
générateur de nombres aléatoires proposé par la norme), cela donne
int main(void)
{
int i = 0, j = 0;
int n = 50000;
double step = 0.1/23456.0;
double seconds = 0.0;
double ref[] {0,0,260,300,310,330,510,850,1020,1050,2280,2490,3390,-1};
Ben, je savais faire en java ou en scheme. J'ai tenté un truc en C et je voulais savoir si je pouvais le programmer comme ça. Désolé, si tu penses que c'était HS.
En fait, l'introduction (à propos des horloges et tout cela) de ton premier message a suscité deux réponses sur le mode « il ne faut pas faire comme cela » concernant en fait le piège de faire une opération de comparaison entre une donnée un tant soit peu aléatoire et une constante (le fait que ce soit des float ne rentre pas en ligne de compte, si le temps est mesuré en ms dans un entier et que tu compares à un multiple de 600000 tu as exactement le même souci). Ce problème n'a rien à voir avec le langage C en soit, même si c'est un contexte où on le rencontre facilement à cause de l'utilisation des float en C, d'où les réponses « automatiques ».
En fait ta vraie question était, comment faire en C une opération sur des flottants. Et évidemment, ce n'est absolument pas hors sujet sur ce groupe, c'est seulement inutile dans le contexte annoncé ;-).
: Cela revient donc à faire un test pour savoir si le temps courant est : un multiple de 10. : : Le code de test ci-dessous m'a l'air de fonctionner. : Maintenant, est-ce la bonne méthode ? : Peux-t-on faire mieux ?
Je ne sais pas si c'est mieux (il faudrait déjà définir l'échelle de jugement pour ce faire), mais je trouve cela un peu compliqué.
Savoir si une valeur double V est un multiple de X : int est_multiple(double v, double x) { return !fmod(v,x); }
Évidemment, codé aussi bêtement, cela ne va pas marcher pour des problèmes d'arrondis. Si V est légèrement supérieur à nX, donc si le résultat de fmod est inférieur à l'epsilon E, cela vaut aussi ; d'où int est_presque_multiple(double v, double x, double e) { return fmod(v,x) < e; }
Mais bien sûr, le problème existe aussi si V est légèrement inférieur... ce qui revient à dire que V+E soit légèrement supérieur à nX, d'où int est_proche_multiple(double v, double x, double e) { return fmod(v+e,x) < e*2.0; }
[ Régler les cas où V, X ou E sont négatifs ou nuls est laissé à l'appréciation du lecteur ; pour ma part j'estime que cela alourdira notablement le code sans avoir un intérêt pratique exceptionnel. ]
Avec l'environnement de test que tu avais mis (et en supposant le générateur de nombres aléatoires proposé par la norme), cela donne
int main(void) { int i = 0, j = 0; int n = 50000; double step = 0.1/23456.0; double seconds = 0.0; double ref[] {0,0,260,300,310,330,510,850,1020,1050,2280,2490,3390,-1};