Est-il garanti par la norme C++ que angle == std::acos(std::cos(angle))
si angle
est dans la plage [0, Pi], ou en d'autres termes est-il possible de restaurer la valeur originale exacte de angle
à partir du résultat de std::cos
en utilisant std::acos
étant donné la limite de plage mentionnée? Les cas marginaux où angle
est infinity
ou NaN
sont omis.Rétablir l'angle exact à partir de std :: cos (angle) en utilisant std :: acos
Répondre
Réponse StoryTeller:
La norme ne peut pas faire cette garantie, tout simplement parce que le résultat de
std::cos
peut ne pas être représentable exactement par undouble
, vous obtenez une erreur de troncature, ce qui aura une incidence sur le résultat destd::acos
.
Est-ce réellement la raison? Est-il impossible de faire une implémentation conforme qui mapperait la valeur à la valeur initiale? – xaxxon
@StoryTeller: Si c'est une dupe, alors ne répondez pas, mais si vous _are_ va répondre, s'il vous plaît faites-le au bon endroit! –
@xaxxon, je ne crains pas. Lorsque la fonction accepte une valeur, elle doit traiter chaque chiffre comme significatif et la valeur comme exactement ce que l'appelant a voulu transmettre. – StoryTeller
De cppreference.com:
” Si aucune erreur ne se produisent, [ACOS] le cosinus d'arc de arg (arccos (arg)) dans l'intervalle [0; π]
En degrés, cela va de 0 à 180 inclusivement, ce qui correspond aux valeurs de cosinus 1 jusqu'à -1 inclusivement.
En dehors de cette plage, vous ne pouvez même pas obtenir une correspondance approximative. Le calcul du cosinus rejette les informations sur l'angle que vous aviez en dehors de cette plage. Il n'y a aucun moyen de récupérer cette information.
Comment l'information est mis au rebut:
d'abord, en degrés, cos (x) = cos (k * 360 + x), par nombre entier arbitraire K. D'autre part, cos (x) = cos (-x). Cela ajoute à beaucoup de valeurs d'angle qui produisent la même valeur de cosinus. Même si tous les lecteurs le savent probablement, mais pour être complet: puisque les sinus sont des cosinus sont des nombres très irrationnels, généralement pas des fractions simples, vous ne pouvez pas espérer des résultats exacts sauf peut-être le cosinus 1, qui correspond à 0 degrés .
"très" irrationnel? Je n'ai jamais entendu parler de ceux qui sont à l'école :) – xaxxon
@xaxxon: pi est un peu irrationnel, mais pas beaucoup, car il devient une suite de chiffres très systématique et simple lorsqu'il est exprimé dans le système de numération factoriel. Mais le sinus de 1,234 degrés, oh, c'est très irrationnel. :-p –
Même mathématiquement, cela est impossible. Par exemple, cos(2*PI)
est 0, mais il en est de même pour cos(4*PI)
.
Ouais, j'ai oublié la période de la fonction. – xaxxon
Selon la norme:
La présente Norme internationale impose aucune exigence sur l'exactitude des opérations à virgule flottante; voir aussi 18.3.2. - Note de fin]
http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4606.pdf
Vrai, mais la raison en est d'éviter de contraindre l'implémentation à utiliser toute la puissance du matériel. Et je pense que ce n'est pas pertinent. Même s'il existait une machine capable de faire des calculs précis à chaque fois, la norme ne peut pas faire cette promesse. D'un point de vue pratique, il faut toujours faire attention en traitant le code numérique. – StoryTeller
@StoryTeller La question spécifiquement posée si la norme fait la garantie et je pense que ce peu dans la norme exclut très spécifiquement la garantie, c'est pourquoi je l'ai ajouté comme une réponse - parce que je pense approche la réponse de la direction demandée dans la question . – xaxxon
Je pense que c'est un peu extensible de lire cette citation. La norme essaie généralement d'être aussi limitée que possible. Mais oui, je peux voir pourquoi cela * pourrait * l'exclure. – StoryTeller
Je ne pense pas. précision à virgule flottante empêche cela. – tkausl
Vous êtes limité par la précision et arrondi – Evgeniy
La norme ne peut pas faire cette garantie. Tout simplement parce que le résultat de 'std :: cos' ne peut pas être représenté exactement par un' double', donc vous obtenez une erreur de troncature, qui affectera le résultat de 'std :: acos'. – StoryTeller