BigInteger + Decimal en Visual Basic

Renaud42_ 70 Messages postés dimanche 18 juin 2017Date d'inscription 6 mai 2018 Dernière intervention - 7 mars 2018 à 22:00 - Dernière réponse : Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention
- 16 mars 2018 à 22:16
Bonsoir,

J'ai fait une méthode pour calculer le nombre d'Euler :

''' <summary>
    ''' Calculate Euler.
    ''' </summary>
    ''' <param name="iterations">Number of iterations.</param>
    Public Shared Function CalculateEuler(Optional iterations As UInt32 = 18) As Decimal
        Dim one As BigInteger = 1
        Dim denominator As BigInteger = 2
        Dim lastmultiplier As Long = 2
        Dim result As Decimal = 2D

        For i As UInt32 = 1 To iterations
            result += BigInteger.Divide(one, denominator).ToString
            denominator *= lastmultiplier + 1
            lastmultiplier += 1
        Next

        ' Example :  2 + 1/(1*2) + 1/(1*2*3) + 1/(1*2*3*4) etc..

        Return result
    End Function


Et le problème est ici que le nombre qui va nous être retourné ici sera 2, et c'est normal car le BigInteger c'est comme un Integer, pas de virgules, donc pas de chiffres après la virgule. Cependant j'avais besoin du BigInteger sinon la variable denominator devenait trop grande pour Long.
Existe-t'il une sorte de "BigDecimal" en VB.NET pour que je puisse retourner ce nombre avec une virgule.
Parce que oui aussi j'ai essayé
result += one / denominator
, le problème ici étant que result est une variable Decimal et que BigInteger et Decimal ne sont pas compatibles. C'est pour ça qu'il me faudrait soit un BigInteger compatible avec les décimales, soit un BigDecimal.

Merci d'avance

Afficher la suite 

Votre réponse

10 réponses

Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 7 mars 2018 à 23:06
0
Utile
Bonsoir

avant de parler de "bigdecimal"
BigInteger.Divide(one, denominator).ToString
ça c'est un string.
que tu "ajoutes" à un Decimal.
C'est pas cohérent.

Ton but c'est de calculer la valeur du nombre d'Euler ou d'afficher le texte comme ton exemple?
Commenter la réponse de Whismeril
Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 7 mars 2018 à 23:35
0
Utile
Je code généralement en C# qui est le langage .Net de base.
Et bien avec des ulong on peut aller jusqu'à 64 itérations, ce qui donne
2.7182818284590452495923189712

En VB.Net, avec le même code, on peut aller jusqu'à 18 ce qui donne
2.7182818284590452349287527284
        Dim one As Decimal = 1
        Dim denominator As ULong = 2
        Dim lastmultiplier As ULong = 2
        Dim result As Decimal = 2D

        For i As UInt32 = 1 To iterations
            result += one / denominator
            lastmultiplier += CULng(1)
            denominator *= lastmultiplier
        Next

        ' Example :  2 + 1/(1*2) + 1/(1*2*3) + 1/(1*2*3*4) etc..

        Return result


C'est une limitation de VB que je ne connaissais pas.
Cependant 18 itérations c'est déjà pas mal, on voit que le résultat change à la 16eme décimale.

Donc en partant du principe que tu veux calculer la valeur, combien d'itération veux tu faire et est ce cohérent de "l'imprécision" du type Decimal?
Renaud42_ 70 Messages postés dimanche 18 juin 2017Date d'inscription 6 mai 2018 Dernière intervention - 8 mars 2018 à 19:45
18 c'est ce que j'avais trouvé au début en max et c'est parce que "denominator" est trop long. C'est pour ça que j'ai utilisé BigInteger pour avoir des nombres avec plus de chiffres pour faire + d'itérations. Le problème c'est que BigInteger n'est pas considéré comme un nombre normal et leur méthode retourne un BigInteger et on ne peut pas lui faire retourner autre chose comme par exemple un Decimal.
Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 8 mars 2018 à 19:51
Oui, mais est vraiment utile de faire plus de 18 itérations?
Renaud42_ 70 Messages postés dimanche 18 juin 2017Date d'inscription 6 mai 2018 Dernière intervention > Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 11 mars 2018 à 22:26
Bah oui, c'est un programme pour essayer de calculer Euler le plus précis possible (faut que je pousse les perfs du Visual Basic au max).
Commenter la réponse de Whismeril
Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 7 mars 2018 à 23:45
0
Utile
Tu peux regarder du coté de BigRational
https://archive.codeplex.com/?p=bcl
Commenter la réponse de Whismeril
Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 14 mars 2018 à 07:39
0
Utile
Bonjour

Ok alord as tu essayé le BigRationnal que je t'ai proposé?

D'autre part, je n'arrive pas à trouver le temps de te répondre correctement.
Ce que je veux t'expliquer est long à rédiger.
Dans un premier temps, je te propose la lecture de cet article Wikipédia.
https://fr.wikipedia.org/wiki/Virgule_flottante

Si tu comprends ou connaitre déjà bien comment ça marche, alors ma phrase suivante aura un sens pour toi, sinon il faudra que tu attendes que j'ai 2 h à te consacrer.

Il est bien possible que la précision que tu cherches à obtenir est impossible, puisque les nombres "n'existent" pas en double ou même décimale, cependant je n'ai pas vérifié, cela fait parti des 2 heures dont j'ai besoin.
Commenter la réponse de Whismeril
pgl10 296 Messages postés samedi 18 décembre 2004Date d'inscription 14 avril 2018 Dernière intervention - 14 mars 2018 à 09:26
0
Utile
Bonjour Renaud42
En allant jusqu'au terme : 1 / (1*2*3* ... *24*25)
et sans aucun des termes suivants, alors le résultat vaut :
85351903640077042215979 / 31399210614030336000000
A bientôt, pgl10
pgl10 296 Messages postés samedi 18 décembre 2004Date d'inscription 14 avril 2018 Dernière intervention - 14 mars 2018 à 11:06
Bonjour tous,
Je précise que la fraction affichée ci-dessus est la valeur exacte du résultat.
On peut aussi ajouter que :
85351903640077042215979 = 3463 x 41231 x 10997999 x 54352957
31399210614030336000000 = (2^21)(3^10)(5^6)(7^3)(11^2)x17x23
Et on peut facilement aller beaucoup plus loin, si on veut !
Cordialement, pgl10
Commenter la réponse de pgl10
Whismeril 11511 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 mai 2018 Dernière intervention - 16 mars 2018 à 22:16
0
Utile
Bonsoir,
j'ai un peu de temps ce soir.

Je vais commencer par une analogie.
Imagine une calculatrice qui ne peut afficher que 10 caractères, mais elle connait la notation scientifique.
On tape 9 999 999 999.
Puis on ajoute 1
Elle affiche
1.0000E+10 => Le résultat est bon, il y a 10 caractères.
On appelle aussi cette notation, un nombre à virgule flottante. On transforme un nombre en un produit, d'un petit nombre décimal et une puissance de 10.

Si on ajoute 1.
Elle affiche toujours
1.0000E+10 => Le résultat n'est plus bon
Il faut ajouter 500 000
Pour qu'elle affiche
1.0001E+10 => changement de valeur, mais résultat toujours pas bon.

Le fait d'utiliser des nombres à virgule flottantes permet d'écrire des nombres très grands (ou très petits) avec seulement 10 caractères disponibles. Mais c'est au détriment de la précision.

En informatique, un float, un double ou un décimal sont des nombres à virgule flottante, sauf qu'il sont écrits en base 2. Et de même que pour la calculatrice, il y a un nombre de bits défini pour le nombre decimal (la mantisse) et un nombre défini de bits pour la puissance de 2 (l'exposant).
Et de même que pour la calculatrice, tout ce qui est entre 10 000 000 000 et 10 000 500 000 vaut 1.0000E+10, et tout ce qui est entre 10 000 500 000 et 10 001 500 000 vaut 1.0001E+10.
Et bien un double ou un decimal ne peuvent pas définir tous les nombres existants. Du coup, quand on les ajoute on arrive pas toujours à ce qu'on espère.

Si je prends la valeur que tu voulais récupérer dans cette autre discussion
http://codes-sources.commentcamarche.net/forum/affich-10083913-recuperer-doc-stocke-sur-web-lettre-par-lettre#1
2.718281828459045235360287471352662497 'les premières décimales de ton site
2.7182818284590452349 '18 itérations et ça diverge là
2.718281828459045249' 64 itérations et ça diverge là


On peut supposer, qu'à la 18ème itération, il manque encore des membres à additionner et que trouver un résultat légèrement inférieur va dans le bon sens.

Cependant, pour 64 itérations, ça diverge avant, et en plus le résultat est supérieur au résultat attendu. Si on faisait une itération de plus on ajouterait un membre et par conséquent on s'éloignerait encore plus du résultat attendu => problème de précision de virgule flottante.
C'est pas avec de l'informatique standard que tu pourras résoudre ce problème.

Si un gars a pris la peine de faire un site juste pour donner les 1000 premières décimales, c'est justement parce que ça n'est pas simple à calculer.
Commenter la réponse de Whismeril

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.