2016-10-15 1 views
3

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

+1

Je ne pense pas. précision à virgule flottante empêche cela. – tkausl

+1

Vous êtes limité par la précision et arrondi – Evgeniy

+1

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

Répondre

3

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 un double, vous obtenez une erreur de troncature, ce qui aura une incidence sur le résultat de std::acos .

+0

Est-ce réellement la raison? Est-il impossible de faire une implémentation conforme qui mapperait la valeur à la valeur initiale? – xaxxon

+0

@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! –

+0

@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

3

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 .

+0

"très" irrationnel? Je n'ai jamais entendu parler de ceux qui sont à l'école :) – xaxxon

+0

@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 –

0

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).

+0

Ouais, j'ai oublié la période de la fonction. – xaxxon

1

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

+0

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

+0

@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

+0

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