Précision racine carré visual studio/c#

Précision racine carré visual studio/c# - C#/.NET managed - Programmation

Marsh Posté le 10-09-2021 à 20:20:24    

Bonjour.
 
Je rencontre un soucis dans le calcul d'une racine carré avec de gros nombre. Je pense que c'est un soucis par rapport à la quantité de nombre après la virgule mais je ne vois pas comment typer mes variables pour corriger ce soucis.
Voici le code :  
 

Code :
  1. double a = 1;
  2. double b = 67108864; // 67 108 864
  3. double acarre = a * a;
  4. double bcarre = b * b;
  5. double d = Math.Sqrt(acarre + bcarre);
  6. // valeur de d : 67108864, résultat impossible par rapport au calcul que je demande
  7. // la calculatrice de windows me donne : 67 108 864,000000007450580596923828


 
Mon projet est un projet console en .NET 5 dans visual studio.
La fonction Math.Sqrt accepte en entré un double qui selon la doc accepte une valeur max de 1.7976931348623157E+308 (donc bien plus que le résultat du carré de  67 108 864).
 
Y'a t-il une solution en typant différemment mes variables ?
Faut-il mieux passer en c++ ou python (je compte partir la dessus car on peut avoir une précision jusqu'à 100bits) ?
 
Merci


Message édité par ragondin le 10-09-2021 à 20:20:42

---------------
Pays et country_code traduits : https://www.iso-country-code.com
Reply

Marsh Posté le 10-09-2021 à 20:20:24   

Reply

Marsh Posté le 11-09-2021 à 23:20:01    

Je viens de transposer mon code en python et ... c'est beaucoup trop lent.
Je n'ai aucun accès disque et ce que je fais en - d'1s en c#, il me faut 52s.

 

J'ai juste 3 boucles qui se charge de faire des sommes puis des racines carrée.


Message édité par ragondin le 11-09-2021 à 23:20:15

---------------
Pays et country_code traduits : https://www.iso-country-code.com
Reply

Marsh Posté le 12-09-2021 à 00:25:45    

Bonjour !
 
Le type "Decimal" offre une plus grande précision (96 bits de mantisse), mais ne l'ayant jamais utilisé, je ne sais pas s'il possède des effets de bord...
 
Bonne continuation !


---------------
On n'est jamais très fort pour ce calcul !
Reply

Marsh Posté le 12-09-2021 à 15:52:39    

Même en castant en décimal, j'ai toujours le même résultat :
 

Code :
  1. decimal d = (decimal) Math.Sqrt(acarre + bcarre); // 67108864 au lieu de 67108864.00000000745...

Message cité 1 fois
Message édité par ragondin le 12-09-2021 à 15:53:26

---------------
Pays et country_code traduits : https://www.iso-country-code.com
Reply

Marsh Posté le 12-09-2021 à 17:45:52    

Un problème de float/double qui ne peut pas représenter exactement certaines valeurs? Si tu as besoin de beaucoup de précision à mon avis tu devrais partir sur une lib' prévue pour ça, genre https://en.wikipedia.org/wiki/GNU_M [...] on_Library pour le C.


Message édité par rat de combat le 12-09-2021 à 17:46:15
Reply

Marsh Posté le 16-09-2021 à 08:17:11    

ragondin a écrit :

Même en castant en décimal, j'ai toujours le même résultat :
 

Code :
  1. decimal d = (decimal) Math.Sqrt(acarre + bcarre); // 67108864 au lieu de 67108864.00000000745...



Si tu appelles ta fonction avec des double et que tu castes en décimal seulement après elle va travailler en double. Donc déjà assure de travailler avec les bons types tout le long ,!
Et si elle n'a pas de signature adaptée, passé par une librairie spécialisée dans le calcul scientifique précis, y en a pas mal...


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
Reply

Marsh Posté le 16-09-2021 à 18:18:13    

Je viens de regarder (j'étais sur smartphone ce matin), Math.Sqrt ne connaît pas les decimal
 
Du coup j'ai testé à l'arrache cette proposition sur SO : https://stackoverflow.com/a/6755197/461444

Code :
  1. decimal a = 1;
  2. decimal b = 67108864; // 67 108 864
  3. decimal acarre = a * a;
  4. decimal bcarre = b * b;
  5. decimal d = Sqrt(acarre + bcarre);
  6. d.Dump();
  7. // valeur de d : 67108864, résultat impossible par rapport au calcul que je demande
  8. // la calculatrice de windows me donne : 67 108 864,000000007450580596923828
  9. // x - a number, from which we need to calculate the square root
  10. // epsilon - an accuracy of calculation of the root from our number.
  11. // The result of the calculations will differ from an actual value
  12. // of the root on less than epslion.
  13. static decimal Sqrt(decimal x, decimal epsilon = 0.0M)
  14. {
  15. if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number" );
  16. decimal current = (decimal)Math.Sqrt((double)x), previous;
  17. do
  18. {
  19.  previous = current;
  20.  if (previous == 0.0M) return 0;
  21.  current = (previous + x / previous) / 2;
  22. }
  23. while (Math.Abs(previous - current) > epsilon);
  24. return current;
  25. }


 
Ca m'a dit : 67108864,000000007450580596925
Ce qui devrait déjà mieux t'aller j'imagine ?


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
Reply

Marsh Posté le 21-09-2021 à 23:37:21    

Bonjour. En effet ça va mieux et c'est très rapide. Merci beaucoup.
Mais idéalement, il faudrait partir sur la solution de rat de combat.
 
J'ai choppé le lib mais pas moyen de comprendre comment elle fonctionne.
 
Merci beaucoup


---------------
Pays et country_code traduits : https://www.iso-country-code.com
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed