La joie des nombre flottants. Binairement parlant les nombres ne sont pas toujours tout à fait égaux. C'est pour ça qu'incrémenter une variable flottante ne l'arrondie pas forcément à un entier et beaucoup de personnes sont surprises au début, voir aussi :
Pour std::to_string, en interne ça utilise sprintf et donc je suppose qu'il rajoute plus de précision. N'étant pas experts en nombre flottant je laisserais d'autres intervenir.
Si tu veux afficher un nombre flottant de manière plus flexible, le mieux est de passer toi même par std::cout/std::printf avec les manipulations qui vont bien (std::setprecision par exemple)
- Edité par markand 29 novembre 2019 à 9:22:29
git is great because Linus did it, mercurial is better because he didn't.
Comme c'est des secondes dans mon cas : 1.71e+10 secondes équivaut à 4750000 heures. Peux de chance que je trouve un fichier vidéo qui dépasse ce timecode. Je vais donc partir avec des double.
Les float, c'est à peu près 7 chiffres significatifs, les double a peu près 13.
Pour comprendre, il faut passer à une notation scientifique :
3902.2 = 3.90220000 * 10^3
et
3902.199951 = 3.902199951 * 10^3
La différence est les deux est de 0.000000049 (*10^3), c'est le 8e chiffre qui change, donc au dela des 7 chiffres significatifs du float.
-> pour la machine, c'est le même nombre. Et si en décimal ça parait biscornu, en binaire, c'est le deuxième nombre qui est plus "rond" que le premier.
Tu auras le même soucis avec les doubles, mais au dela de 13 chiffres significatifs.
Par défaut, std::string fait comme le printf, affiche 6 chiffres après la virgule, en changeant la précision, tu en afficheras moins, et il arrondira le 0.1999 en 0.2
Garder en tête que les float/double ont été pensés pour la physique, par les maths, ils ne donnent pas des résultats exacts mais des résultats garantis à une précision près. Et en effet en physique, quand tu mesures des distances entre des villes, tu te moques que ce soit au centimètre près...
Merci, je comprends mieux, mais je trouve bizarre que l'on me permettre d'aller au delà du nombre de chiffre significatif alors qu'ils ne sont pas utilisable.
Edit : pour erreur dans mon code...
Je n'ai pas l'impression que je puisse forcer la précision d'un float en dehors du moment de l'affichage
Je me demande si je n''aurai pas intérêt, à multiplier mes valeurs en seconde par 1000 pour les avoir en "milli seconde" et les stocker dans des entiers.... (voir 100000 pour prendre en compte des hautes fréquences d’échantillonnages audio que l'on peu rencontrer parfois de 192000hz)
L'initiatilisation des chiffres non-significatifs pourraient se faire avec des zéros plutôt qu'avec des chiffres "aléatoires"
Les nombres : 76293945 sont là, je peux les lire, ils ont bien été rajouté par une action. Ils ne semblent pas aléatoire.
Pourquoi ne pas les mettre à zéro, ou pouvoir les mettre à zéro ?
Fvirtman a simplifié, mais comme il l'a indiqué l'arrondi se fait en binaire, et le nombre de chiffre significatif n'est pas de 13 mais de la mantisse en binaire défini par la norme que suis le système pour sa représentation des flottant, et dans la norme IEEE 754 après conversion en décimale on tombe autour de 13 chiffres significatifs.
Il faut que tu identifies ton besoin en précision lorsque tu utilise des nombres flottants, ça arrive que celle native ne soit pas suffisante mais c'est quand même étonnant. Je crois qu'il existe des libs mathématiques pour remédier au besoin de précision, je sais pas à quel point. Sinon tu ne pourrais pas travailler avec des entiers ?
Dream on, Dream on, Dream until your dream comes true
Oui merci, je viens de comprendre les indications de Fvirtman sur les nombres significatifs. Je n'aurai pas besoin de passer par des entiers.
Le calcul avec des float est juste mais sa conversion en string dépend de la précision de la fonction to_string() (qui est faible pour le float).
J'ai donc fait une estimation de mes besoins et le double s'adapte mieux.
Le pire des cas pour moi serait d'avoir un fichier audio de 48h avec 6 chiffres après la virgule pour la précision : 48h*60min*60sec + quelques nano secondes = 172800.984502
Hors avec ce type de nombre je vais au delà des possibilités du float qui est limité à 7 chiffres significatifs.
Pour le cas du 3902.2 la fonction to_string(float) le récupère en binaire donc plutôt avec 6 chiffres après la virgule (3902.200000) on dépasse là aussi la précision des 7.
3902.2 est un raccourcis de 3902.200000, ce qui a dû me mettre sur la mauvaise piste.
Merci pour vos explications, je pense avoir compris et j'ai aussi une solution en utilisant les double.
Un flottant de 64 bits avec 52 bits de mantisse a toujours au moins 15 chiffres significatifs si je ne me trompe pas (16 dans de nombreux exposants), et non 13. 13 chiffres significatifs, ce serait un flottant avec entre 43 et 46 bits de mantisse.
Le pire des cas pour moi serait d'avoir un fichier audio de 48h avec 6 chiffres après la virgule pour la précision : 48h*60min*60sec + quelques nano secondes = 172800.984502
Alors oui, si tu as besoin de davantage de chiffres, tu peux utiliser des double. Mais je ne comprends pas bien ton besoin. Tu veux stocker le temps d'une vidéo de 48h. Déjà, les vidéos de 48 heures il y en a peu, et ensuite et surtout, tu veux les stocker à la nanoseconde près ? En général les fichiers vidéos stockent à la seconde près... Si vraiment tu veux stocker des frames supplémentaires, tu peux descendre, allez, au centième près (ce qu'aucun format connu ne fait), mais jamais à la nano seconde ?
La, je n'essaie pas de te dire d'utiliser quand même les float, tu peux utiliser les double, pas de soucis, mais je ne comprends pas bien ce que tu fais...
C'est pour prendre en compte les passages à minuit.
Peut probable d'avoir un fichier d'un durée de plus de 24h effectivement.
Mais le fichier peut enregistrer le timecode du début de l'enregistrement. Si l'enregistrement commence à 23h30, et qu'il dépasse deux heures, on se retrouve parfois avec des aberrations.
Le timecode de début sera de : 23:30:00 , la durée de 02:00:00 et donc le timecode de fin : 25:30:00 (ou 02:30:00 si on repasse à zéro).
Ça dépend du type d'enregistreur, de l'encodeur, du format de fichier et de l'endroit ou est inscrit de timecode et comme il n'y a pas de norme, je préfère voir large.
Les temps sont notés avec 6 chiffres après la virgule. Si pour les images ce n'est pas probant, à 25 images par secondes, pour l'audio à 480000 échantillons (sample) par secondes ça l'est plus. Si on ajoute le fait que certains fichiers ne sont pas coupé correctement, on se retrouve avec des nombres de sample pas toujours rond.
On note souvent le timecode en image 23:30:00:10 (23h30 et 10 images). Pour le son je pense que c'est moins le cas, mais je préfère le faire dans le but de diagnostiquer l'état d'un fichier...
Si les temps sont notés avec 6 chiffres après la virgule, c'est parce qu'ils utilisent printf ou std::to_string pour les afficher, mais je parie que ce n'est pas précis à la microseconde près, même pas la milliseconde je pense.
Et les nombres ne sont pas ronds.... devine pourquoi
Au niveau de l’échantillonnage de ffmpeg, on utilise une AVRational (généralement {1,frame_rate}) puis l'index de la frame à encoder. Les codecs s'occupent d'enregistrer avec un maximum de précision. Je ne sais plus par contre si cette valeur est toujours fixe ou si certains codecs autorisent à la changer.
Cette histoire de vidéo qui revient en arrière est aussi une connerie. On n'utilise pas l'heure réelle pour enregistrer, mais le temps écoulé (un chronomètre). L'heure réelle est une information superflue qu'un décodeur n'a pas besoin. Au pire, cela fait partie des méta-données pour indiquer quand la vidéo est construite.
Perso, je n'ai toujours pas compris ton besoin initial.
Le décodeur n'est pas le destinataire final de l'application, mais des utilisateurs en cher et en os. L'information de temps sous forme de seconde n'est pas d'une grande aide dans ce cas là. De plus le décodage peut être piloté par d'autre machine, qui elles ne savent pas toujours faire un passage à minuit correctement...(même si c'est de plus en plus rare)
Dans l'audiovisuel on travaille toujours à l'image prés, le timecode représente mieux les durées et les temps . Dans le cadre d'un fichier contenant du son, l'information de framerate n'est pas toujours accessible. Pour le son, je ne sais pas si cela à son importance d'avoir le nombre de sample mais je préfère l'indiquer le plus correctement maintenant, j'y trouverai peut-être un intérêt plus tard.
Conversion de float étrange
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
git is great because Linus did it, mercurial is better because he didn't.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html