Nombres premiers : vérification à plusieurs
Nombres premiers : vérification à plusieurs
Bonjour à vous,
dans un but mathématique assez concrèt, je me suis remis à "miner" des nombres premiers.
À la base, je prépare 100000 nombres premiers en moins d'une demi seconde, puis je simplifie des fractions avec. C'est le même algo pour chercher ces nombres premiers comme pour simplifier une fraction : on divise par une liste successive de facteurs, et on agit en fonction du restant calculé.
Puis, m'est venue la bête et gratuite idée de "miner" plus de nombres premiers que cent-mille, puis de les enregistrer dans un fichier. Le rapport quantité/durée de préparation est alors nettement supérieur : on a pleins de nombres premiers (en l'occurence, plusieurs millions) qui se "succèdent" depuis le 2, et c'est chargé et prêt en moins d'une demi seconde.
J'ai, ensuite, toujours bêtement, eu l'idée de baisser la performance de "minage" et de laisser tourner l'ordinateur. C'est un portable avec une LED qui me prévient, et ce CPU est assez surprenant : il bouffe 2 watts ! Il fait 2000 divisions de test, puis pionce 16 millisecondes, et répète ce cycle pour 2 Wh/H, j'estime qu'on ne va pas me reprocher de gaspiller de l'énergie.
Résultat : je commence à avoir un fichier avec plusieurs dizaines de millions de nombres premiers. En brut 64 bits, c'est 8 octets par nombre premier : ça prend de la place.
J'aimerais compresser le tout, trouver un compromis taux/durée assez correct.
Et c'est là que je tique : si mon algo était faux ! Méthode de recherche, enregistrement : pas sûr que ce soit parfait...
Et puis, bien qu'il y a des "compresseurs" natifs, je suis séduit par des compressions plus simples donc, peut-être plus rapides : ça demande à tester. Et pour tester, il est inutile de tester quelquechose qui a une erreur : un nombre premier qui ne le serait pas, ou bien, un nombre premier qui manque. J'ai quelques statistiques aussi, un peu simplistes, quand Windows ne fait pas n'importe quoi avec les fichiers (c'est un boulet, c'est lourd). Et une de ces statistiques me plaît suffisamment, pour avoir envie de creuser un peu. En l'occurence, c'est l'aspect quand même très stable des écarts entre nombres premiers : des nombres premiers de 8 chiffres ne s'écartent pas de plus de 2^8. Autrement dit, un nombre de 28 bits est l'image d'une somme d'écarts, et ces écarts font, au maximum 8 bits. Ce qui fait une compression de 70% avec simplement une addition pour seul algo de décompression.
Mais, pour ça, il faut être sûr de ne pas avoir fait d'erreurs. Et c'est là que je sollicite des passionnés : j'aimerais qu'on partage différents checksums, d'abord, d'une suite symbolique (les 64 premiers nombres premiers, par exemple), puis des checksums de listes de plus en plus conséquentes.
Alors, je ne fais pas la course. Je me suis fixé un but : collecter tous les nombres premiers < à 2^32. Ça permet déjà des sacrées fractions à 9 chiffres. C'est assez "carré" pour un x64 (ou x86 avec algo non signé), avec un entier x64, on a 2 longs dedans, donc une fraction qui "tient" des milliardièmes infiniment précis entre -2 et +2. Et puis, avec deux quads, on a une belle fraction, qui tient des milliardièmes de milliardièmes infiniment précis en -2 et +2. Et, par la même, avec 4 quads, on a des plages irréprochables avec cette même échelle de précision. Avec tous les nombres premiers inférieurs à 2^32, les fractions décrites "en sus" sont parfaitement simplifiables.
J'aimerais que ces nombres premiers < 2^32 tiennent dans un fichier de quelques mégas, voire 1 seul méga-octet.
Et, me connaisant, je ne fais pas de "demi-couille" : traduction, quand je couille, c'est la grosse merde.
Par application axiomatique, vous dire la valeur du Nième nombre premier ne garantit pas que je n'ai pas fait une double faute de recherche (un excès plus un défaut... Un faux positif accompagné d'un faux négatif).
Quel algorithme de hachage permet cette garantie ? (Et donc de se communiquer diverses clés pas trop longues pour s'assurer d'une collection parfaite)
dans un but mathématique assez concrèt, je me suis remis à "miner" des nombres premiers.
À la base, je prépare 100000 nombres premiers en moins d'une demi seconde, puis je simplifie des fractions avec. C'est le même algo pour chercher ces nombres premiers comme pour simplifier une fraction : on divise par une liste successive de facteurs, et on agit en fonction du restant calculé.
Puis, m'est venue la bête et gratuite idée de "miner" plus de nombres premiers que cent-mille, puis de les enregistrer dans un fichier. Le rapport quantité/durée de préparation est alors nettement supérieur : on a pleins de nombres premiers (en l'occurence, plusieurs millions) qui se "succèdent" depuis le 2, et c'est chargé et prêt en moins d'une demi seconde.
J'ai, ensuite, toujours bêtement, eu l'idée de baisser la performance de "minage" et de laisser tourner l'ordinateur. C'est un portable avec une LED qui me prévient, et ce CPU est assez surprenant : il bouffe 2 watts ! Il fait 2000 divisions de test, puis pionce 16 millisecondes, et répète ce cycle pour 2 Wh/H, j'estime qu'on ne va pas me reprocher de gaspiller de l'énergie.
Résultat : je commence à avoir un fichier avec plusieurs dizaines de millions de nombres premiers. En brut 64 bits, c'est 8 octets par nombre premier : ça prend de la place.
J'aimerais compresser le tout, trouver un compromis taux/durée assez correct.
Et c'est là que je tique : si mon algo était faux ! Méthode de recherche, enregistrement : pas sûr que ce soit parfait...
Et puis, bien qu'il y a des "compresseurs" natifs, je suis séduit par des compressions plus simples donc, peut-être plus rapides : ça demande à tester. Et pour tester, il est inutile de tester quelquechose qui a une erreur : un nombre premier qui ne le serait pas, ou bien, un nombre premier qui manque. J'ai quelques statistiques aussi, un peu simplistes, quand Windows ne fait pas n'importe quoi avec les fichiers (c'est un boulet, c'est lourd). Et une de ces statistiques me plaît suffisamment, pour avoir envie de creuser un peu. En l'occurence, c'est l'aspect quand même très stable des écarts entre nombres premiers : des nombres premiers de 8 chiffres ne s'écartent pas de plus de 2^8. Autrement dit, un nombre de 28 bits est l'image d'une somme d'écarts, et ces écarts font, au maximum 8 bits. Ce qui fait une compression de 70% avec simplement une addition pour seul algo de décompression.
Mais, pour ça, il faut être sûr de ne pas avoir fait d'erreurs. Et c'est là que je sollicite des passionnés : j'aimerais qu'on partage différents checksums, d'abord, d'une suite symbolique (les 64 premiers nombres premiers, par exemple), puis des checksums de listes de plus en plus conséquentes.
Alors, je ne fais pas la course. Je me suis fixé un but : collecter tous les nombres premiers < à 2^32. Ça permet déjà des sacrées fractions à 9 chiffres. C'est assez "carré" pour un x64 (ou x86 avec algo non signé), avec un entier x64, on a 2 longs dedans, donc une fraction qui "tient" des milliardièmes infiniment précis entre -2 et +2. Et puis, avec deux quads, on a une belle fraction, qui tient des milliardièmes de milliardièmes infiniment précis en -2 et +2. Et, par la même, avec 4 quads, on a des plages irréprochables avec cette même échelle de précision. Avec tous les nombres premiers inférieurs à 2^32, les fractions décrites "en sus" sont parfaitement simplifiables.
J'aimerais que ces nombres premiers < 2^32 tiennent dans un fichier de quelques mégas, voire 1 seul méga-octet.
Et, me connaisant, je ne fais pas de "demi-couille" : traduction, quand je couille, c'est la grosse merde.
Par application axiomatique, vous dire la valeur du Nième nombre premier ne garantit pas que je n'ai pas fait une double faute de recherche (un excès plus un défaut... Un faux positif accompagné d'un faux négatif).
Quel algorithme de hachage permet cette garantie ? (Et donc de se communiquer diverses clés pas trop longues pour s'assurer d'une collection parfaite)
Re: Nombres premiers : vérification à plusieurs
Perso, je commence sur cette base :
Code : Tout sélectionner
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; SPH(2022) - Lister les nombres premiers ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Tester les nombres de 2 a :
nombre=10000
timer=ElapsedMilliseconds()
Dim nb(nombre) : nb(0)=1 : nb(1)=2
For nb=3 To nombre Step 2
sq=Sqr(nb)
For u=3 To sq Step 2
If nb%u=0
Goto stop
EndIf
Next
nb(0)+1
nb(nb(0))=nb
stop:
Next
Debug "Les nombres premiers de 2 à "+Str(nombre)+" ont été trouvé en "+Str(ElapsedMilliseconds()-timer)+" ms"
For i=1 To nb(0)
Debug nb(i)
Next
End
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
Re: Nombres premiers : vérification à plusieurs
Salut SPH,
je suis exactement sur ce même départ.Je suis en quads.Je vois x86 dans ta signature : SizeOf(integer) t'affiche 4 ?
je suis exactement sur ce même départ.
Code : Tout sélectionner
nb(0) = 1 ; le dernier index de la liste
nb(1) = 2
Code : Tout sélectionner
Debug SizeOf(integer) ; affiche 8
Re: Nombres premiers : vérification à plusieurs
Ollivier a écrit : ↑dim. 07/août/2022 19:48 Salut SPH,
je suis exactement sur ce même départ.Je suis en quads.Code : Tout sélectionner
nb(0) = 1 ; le dernier index de la liste nb(1) = 2
Je vois x86 dans ta signature : SizeOf(integer) t'affiche 4 ?Code : Tout sélectionner
Debug SizeOf(integer) ; affiche 8
Code : Tout sélectionner
Debug SizeOf(integer)
===
En fait, je suis sur 2 ordinateurs différents. Alors, comme j'utilise le desktop, je viens de modifier ma signature.
Bon, comme tu as vu dans ma routine, j'ouvre un dim :
Code : Tout sélectionner
Dim nb(nombre)
Quel est ton code ?
J'ai cru comprendre que tu pouvais tester la primalité d'un nombre avec une formule. Laquelle ?
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
Re: Nombres premiers : vérification à plusieurs
C'est pour aller, cool, vers un nombre premier autour de 4 milliards. (le plus grand nombre premier qu'on peut stocker dans 32 bits non signé, en fait)
Code : Tout sélectionner
Global FileName.s = "primes.dta" ; bien régler le bon chemin de fichier
; le tableau
Structure primes
Array p.i(0)
EndStructure
; pour rajouter un nombre
Procedure primesAdd(*this.primes, n)
With *this
Define max = ArraySize(\p() )
Define i = \p(0) + 1
Repeat
If i > max
max + 1
max << 1
max - 1
EndIf
Until i <= max
ReDim \p(max)
If i > \p(0)
\p(0) = i
EndIf
\p(i) = n
EndWith
EndProcedure
; pour afficher la liste
Procedure primesDebug(*this.primes)
With *this
Debug ArraySize(\p() )
For i = 0 To \p(0)
Debug Str(i) + " : " + Str(\p(i) )
Next
EndWith
EndProcedure
; retourne un facteur premier détecté dans n
Procedure primesFactor(*this.primes, n)
Static j
With *this
For i = 1 To \p(0)
If j > 2047
j = 0
Delay(16)
EndIf
j + 1
p = \p(i)
If n % p = 0
ProcedureReturn \p(i)
EndIf
If p * p > n
Break
EndIf
Next
EndWith
ProcedureReturn 0
EndProcedure
; pour sauvegarder
Procedure primesSave(*this.primes, file.s)
With *this
Define size = (ArraySize(\p() ) + 1) * SizeOf(integer)
Define addr = @\p(0)
Define fileN = CreateFile(#PB_Any, file)
WriteData(fileN, addr, size)
CloseFile(fileN)
EndWith
EndProcedure
; pour charger la liste
Procedure primesLoad(*this.primes, file.s)
With *this
Define size = FileSize(file) / SizeOf(integer) - 1
If size <= 0
ReDim \p(1)
\p(0) = 1
\p(1) = 2
Else
ReDim \p(size)
size + 1
size * SizeOf(integer)
Define addr = @\p(0)
Define fileN = ReadFile(#PB_Any, file)
ReadData(fileN, addr, size)
CloseFile(fileN)
EndIf
EndWith
EndProcedure
; pour quitter avec la croix rouge d'une fenêtre
Procedure quit()
Static win
If win
If WindowEvent() = #PB_Event_CloseWindow
CloseWindow(win)
ProcedureReturn 1
EndIf
Else
win = OpenWindow(#PB_Any, 0, 0, 400, 300, "...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EndIf
EndProcedure
; pour quitter avec [Alt+F4]
Procedure quit2()
Static win
If win
If WindowEvent() = #PB_Event_CloseWindow
CloseWindow(win)
ProcedureReturn 1
EndIf
Else
win = OpenWindow(#PB_Any, 0, 0, 1, 1, "...", #PB_Window_Maximize | #PB_Window_BorderLess)
SetWindowColor(win, 0)
EndIf
EndProcedure
; pour rechercher et stocker les nombres premiers
Procedure primesSearch(*this.primes, i, *quit)
With *this
Repeat
If primesFactor(*this, i) = 0
primesAdd(*this, i)
EndIf
i + 1
Until CallFunctionFast(*quit)
EndWith
EndProcedure
; principe
Define *p.primes = AllocateMemory(SizeOf(primes) )
InitializeStructure(*p, primes)
primesLoad(*p, fileName)
n = *p\p(0)
n = *p\p(n)
n + 1
primesSearch(*p, n, @quit2() )
primesSave(*p, fileName)
MessageRequester(Str(*p\p(0) ), Str(*p\p(*p\p(0) ) ) )
Re: Nombres premiers : vérification à plusieurs
Pour résumer
1) bien préciser un fichier avec chemin complet en 1ère ligne
2) couper le débugger et démarrer le programme
3) avec Alt+Tab tu peux faire autre chose (vérifier les ressources CPU)
4) ça enregistre en retournant dessus (l'économiseur noir) et tapant Alt+F4
5) Il enregistre et t'affiche le nombre de nombres premiers trouvés et le dernier nombre premier qui a été trouvé.
Il est juste optimisé avec la méthode de Fibonacci pour éviter de trop diviser.
Etrangement, je le laisse tester tous les nombres même les pairs. Ça évite quelques erreurs de statistique. Et le CPU semble les prédire, donc, tant qu'à faire.
Mais comment avoir confiance à une empreinte ?
1) bien préciser un fichier avec chemin complet en 1ère ligne
2) couper le débugger et démarrer le programme
3) avec Alt+Tab tu peux faire autre chose (vérifier les ressources CPU)
4) ça enregistre en retournant dessus (l'économiseur noir) et tapant Alt+F4
5) Il enregistre et t'affiche le nombre de nombres premiers trouvés et le dernier nombre premier qui a été trouvé.
Il est juste optimisé avec la méthode de Fibonacci pour éviter de trop diviser.
Etrangement, je le laisse tester tous les nombres même les pairs. Ça évite quelques erreurs de statistique. Et le CPU semble les prédire, donc, tant qu'à faire.
Mais comment avoir confiance à une empreinte ?
Re: Nombres premiers : vérification à plusieurs
Bonjour Ollivier
Je vois que tu es toujours sur une optimisation des nombres premiers.
J’ai testé ton prg, mais mon écran s’est trouvé dans le noir.
Avec alt F4 j’ai pu l’arrêter
J’ai ensuite réalisé le prg suivant pour vérifier ce qui il avait dans le fichier primes.dta
Les cent premiers nb sont bien premiers.
Je voudrai savoir quel est ton objectif car tous les nombre dans le fichier ne sont pas compressés.
Après lancement du prg peut-on garder la possibilité de continuer à travailler.
A+
Je vois que tu es toujours sur une optimisation des nombres premiers.
J’ai testé ton prg, mais mon écran s’est trouvé dans le noir.
Avec alt F4 j’ai pu l’arrêter
J’ai ensuite réalisé le prg suivant pour vérifier ce qui il avait dans le fichier primes.dta
Les cent premiers nb sont bien premiers.
Je voudrai savoir quel est ton objectif car tous les nombre dans le fichier ne sont pas compressés.
Après lancement du prg peut-on garder la possibilité de continuer à travailler.
Code : Tout sélectionner
Global FileName.s = "g:\primes.dta"
If ReadFile(0, FileName)
length = Lof(0) ; Lit la taille en octets du fichier
*MemoryID = AllocateMemory(length) ; alloue un bloc mémoire de la taille du fichier
If *MemoryID
bytes = ReadData(0, *MemoryID, length) ; Lit les données du fichier et les place dans le bloc mémoire
Debug "Nombre d'octets lus: " + Str(bytes)
EndIf
CloseFile(0)
EndIf
nbprem=bytes/4
Debug _n(length)+_n(nbprem)
np=0
np0=0
For i =0 To length Step 4
prem=PeekI(*MemoryID+i)
If prem>0
Debug prem
np+1
Else
np0+1
EndIf
Next
Debug _n(np)+_n(np0)+_n(nbprem)+_n(np+np0)
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Re: Nombres premiers : vérification à plusieurs
Bonjour PAPIPP,
je dois avouer être ravi par ton intervention. Je pensais forcément à toi qui a d'ailleurs raconté avoir collectionné et stocké des nombres premiers dans des fichiers. Il faudra que je retrouve le lien de cette description.
Alors, aucun nombre n'est compressé dans ce programme : ils font << brutalement 8 octets pièce >> !
Avant de reprendre le travail, et, étant un peu malade (un comble pour un été), je testais les différents compresseurs de pureBasic et aucun ne détecte que les gaps, les écarts ne dépassent pas 256, les 8 bits d'un octet.
Je tâcherai de poster le dernier petit code pour demain matin, qui visualise cette évolution moyenne de l'écart, avec, grâce à ArS une illustration, sur 20 millions de valeurs environ. On a une moyenne de 20, bien en-deça de 256.
Cet écart moyen grandit mais ça laisse le temps.
Mon but :
- chercher les nombres premiers de 32 bits (jusqu'à 4 milliards environ)
- les compresser (tenter la barre du seul mégaoctet)
- les utiliser pour un programme de calcul mathématiques (simplification des fractions et des racines) de nombres de 64 bits
Pour le petit programme actuel, il met dans le noir ! Effectivement, c'est le but : l'exécuter, comme un économiseur d'écran (si on n'utilise pas l'ordinateur) ou pas. En tapant Alt+Tab, on bascule vers toute autre tâche. Et on peut remarquer que le "minage", la recherche des nombres premiers prend peu de ressources CPU (moi, j'ai 4% qui s'affiche).
Le but à plusieurs, c'est de vérifier qu'on a les mêmes nombres premiers. Il y a une librairie native dans pureBasic, mais, un peu comme la librairie sur la compression de données qui n'arrive pas à compresser mieux que ce que l'on peut faire soi sans trop de difficulté (si chaque écart entre deux nombres premiers est inférieur à 256, par simple addition/soustraction, on compresse manuellement les nombres premiers dans un seul octet : je ne sais pas, par contre si cette limite est franchie pour les nombres premiers jusqu'à 4 milliards environ, en tout cas, jusqu'à 400 millions environ, pas de souci, si je ne me suis pas trompé de nombres !) j'ai donc peur que les différentes fonctions de signature (CRC32, etc...) ne m'induisent pas en erreur, et n'induisent pas en erreur un groupe de personnes qui vérifieraient entre eux, par ce type de signature, qu'ils ont la bonne liste des nombres premiers.
Quand tu quittes le programme avec Alt+F4, il y a un message qui s'affiche : dans mon cas, j'ai 21995833 (en titre de message), c'est la quantité totale de nombres premiers qu'il a stockés et enregistrés dans le fichier (c'est Alt+F4 qui déclenche l'enregistrement, petite subtilité). Et j'ai, dans ce message, 413075863, c'est le dernier nombre premier qu'il a trouvé.
Or, tout comme les empreintes (CRC32, etc...), vous dire que le 21 995 833 ième nombre premier est 413 075 863, ne me semble pas être une preuve suffisante, que j'ai bien enregistré la bonne liste complète, et sans erreur, des nombres premiers entre 2 et 413 075 863, inclus.
En quelle méthode, pourrait-on avoir confiance ?
Et très heureux de te lire.
PS : si toi, ou quiconque, souhaitez me "dépasser" avec ce programme, il y a une valeur à augmenter dedans qui est ici à 2047 : c'est le nombre de vérifications que le programme exécute avant de rendre la main avec Delay() et donc, d'attendre d'avoir, à nouveau la main quelques 16 millisecondes plus tard.
Par contre, attention à votre mémoire vive, parce que tout reste en mémoire tant que vous ne quittez pas le programme : il n'y a pas d'enregistrement partiel.
je dois avouer être ravi par ton intervention. Je pensais forcément à toi qui a d'ailleurs raconté avoir collectionné et stocké des nombres premiers dans des fichiers. Il faudra que je retrouve le lien de cette description.
Alors, aucun nombre n'est compressé dans ce programme : ils font << brutalement 8 octets pièce >> !
Avant de reprendre le travail, et, étant un peu malade (un comble pour un été), je testais les différents compresseurs de pureBasic et aucun ne détecte que les gaps, les écarts ne dépassent pas 256, les 8 bits d'un octet.
Je tâcherai de poster le dernier petit code pour demain matin, qui visualise cette évolution moyenne de l'écart, avec, grâce à ArS une illustration, sur 20 millions de valeurs environ. On a une moyenne de 20, bien en-deça de 256.
Cet écart moyen grandit mais ça laisse le temps.
Mon but :
- chercher les nombres premiers de 32 bits (jusqu'à 4 milliards environ)
- les compresser (tenter la barre du seul mégaoctet)
- les utiliser pour un programme de calcul mathématiques (simplification des fractions et des racines) de nombres de 64 bits
Pour le petit programme actuel, il met dans le noir ! Effectivement, c'est le but : l'exécuter, comme un économiseur d'écran (si on n'utilise pas l'ordinateur) ou pas. En tapant Alt+Tab, on bascule vers toute autre tâche. Et on peut remarquer que le "minage", la recherche des nombres premiers prend peu de ressources CPU (moi, j'ai 4% qui s'affiche).
Le but à plusieurs, c'est de vérifier qu'on a les mêmes nombres premiers. Il y a une librairie native dans pureBasic, mais, un peu comme la librairie sur la compression de données qui n'arrive pas à compresser mieux que ce que l'on peut faire soi sans trop de difficulté (si chaque écart entre deux nombres premiers est inférieur à 256, par simple addition/soustraction, on compresse manuellement les nombres premiers dans un seul octet : je ne sais pas, par contre si cette limite est franchie pour les nombres premiers jusqu'à 4 milliards environ, en tout cas, jusqu'à 400 millions environ, pas de souci, si je ne me suis pas trompé de nombres !) j'ai donc peur que les différentes fonctions de signature (CRC32, etc...) ne m'induisent pas en erreur, et n'induisent pas en erreur un groupe de personnes qui vérifieraient entre eux, par ce type de signature, qu'ils ont la bonne liste des nombres premiers.
Quand tu quittes le programme avec Alt+F4, il y a un message qui s'affiche : dans mon cas, j'ai 21995833 (en titre de message), c'est la quantité totale de nombres premiers qu'il a stockés et enregistrés dans le fichier (c'est Alt+F4 qui déclenche l'enregistrement, petite subtilité). Et j'ai, dans ce message, 413075863, c'est le dernier nombre premier qu'il a trouvé.
Or, tout comme les empreintes (CRC32, etc...), vous dire que le 21 995 833 ième nombre premier est 413 075 863, ne me semble pas être une preuve suffisante, que j'ai bien enregistré la bonne liste complète, et sans erreur, des nombres premiers entre 2 et 413 075 863, inclus.
En quelle méthode, pourrait-on avoir confiance ?
Et très heureux de te lire.
PS : si toi, ou quiconque, souhaitez me "dépasser" avec ce programme, il y a une valeur à augmenter dedans qui est ici à 2047 : c'est le nombre de vérifications que le programme exécute avant de rendre la main avec Delay() et donc, d'attendre d'avoir, à nouveau la main quelques 16 millisecondes plus tard.
Par contre, attention à votre mémoire vive, parce que tout reste en mémoire tant que vous ne quittez pas le programme : il n'y a pas d'enregistrement partiel.
Re: Nombres premiers : vérification à plusieurs
Je constate avec surprise :
- que 436 273 009 semble être un nombre premier
- que 436 273 291 semble être aussi un nombre premier
- qu'il n'y a pas de nombre premier entre ces deux valeurs
donc :
- la différence entre ces deux nombres étant 282;
- 282 étant supérieur à 256;
ma compression du fichier va fonctionner jusqu'à la position qui précède ce gap.
Il est fort probable donc que le 1er fichier fasse 23 méga 163 kilo et 298 octets. Chaque octet sera non signé entre 0 et 255, et représentera un gap entre 2 et 436 273 009.
- que 436 273 009 semble être un nombre premier
- que 436 273 291 semble être aussi un nombre premier
- qu'il n'y a pas de nombre premier entre ces deux valeurs
donc :
- la différence entre ces deux nombres étant 282;
- 282 étant supérieur à 256;
ma compression du fichier va fonctionner jusqu'à la position qui précède ce gap.
Il est fort probable donc que le 1er fichier fasse 23 méga 163 kilo et 298 octets. Chaque octet sera non signé entre 0 et 255, et représentera un gap entre 2 et 436 273 009.
Re: Nombres premiers : vérification à plusieurs
@Ollivier
Voici les deux prg qui permettent de trouver les nb premiers entre deux zones
le premier prg génère les tables des différences avec soit p_fact(x) x peut prendre les valeur 5 7 11 13 17 19 23 pour chacune des tables
Ce prg est indispensable pour utiliser le prg de recherche par zone.
Le deuxième est le prg de recherche les nb premiers entre deux zones
il fonctionne de 1 à 2¨(64)-2
il faut éviter d'utiliser des zones trop importantes
fwell à l'époque avait contrôler ce prg et il avait confirmé les résultats
Ici le deuxième prg de recherche par zone
A+
Voici les deux prg qui permettent de trouver les nb premiers entre deux zones
le premier prg génère les tables des différences avec soit p_fact(x) x peut prendre les valeur 5 7 11 13 17 19 23 pour chacune des tables
Ce prg est indispensable pour utiliser le prg de recherche par zone.
Le deuxième est le prg de recherche les nb premiers entre deux zones
il fonctionne de 1 à 2¨(64)-2
il faut éviter d'utiliser des zones trop importantes
fwell à l'époque avait contrôler ce prg et il avait confirmé les résultats
Code : Tout sélectionner
; exemple des p_fact(x)
; p_fact(x)--modulo-----------------Nb_occurrences des différences--------Taux-----------Gain
; 3__________6__________________________2_________________________________0,3333_________66,66%
; 5__________30_________________________8_________________________________0,2666_________73,33%
; 7__________210________________________48________________________________0,2285_________77,14%
; 11_________2310_______________________480_______________________________0,2078_________79,22%
; 13_________30030______________________5760______________________________0,1918_________80,81%
; 17_________510510 ____________________92160_____________________________0,18052________81,94%
; 19_________9699690____________________1658880___________________________0,17102________82,89%
; 23_________223092870__________________36495360__________________________0,16358________83,64%
; Macro _q_t_
; "
; EndMacro
; Macro _n (__n)
; _q_t_#__n#=_q_t_+Str(__n)+" "
; EndMacro
; Macro _Q (__Q)
; _q_t_#__Q#=_q_t_+Str(__Q)+" "
; EndMacro
EnableExplicit
Define col$="",dif$=""
OpenConsole("Résultats partiel")
Dim T_MODULO.l(12)
Structure colonne
; nb.q
prem.a
; dif_prec.l
dif_prec.a
; Dif_act.l
EndStructure
Structure DIVIS
NBPFACT.a
PREMDIV.l
NBSEQ.l
MODULO.q
; Array TDIF.a(40000000) ;; *** ATTENTION A utiliser avec DATA.A et read.A mais très lent avec p_fact(23) P_fact(19) est préférable remplacer 40 par 2
Array TDIF.a(40000000)
EndStructure
Define SEQD.DIVIS,mess$,nb$,nbs,rest.l,i,modulo,elem,NBprem,Tdep.q,inb,inbp,prem_p,PREM_NB_PREM_AV,NB_PREM,SOM_DIF,vecteur$,NBSEQ,lvecteur,rapportq.d,RAPPORT.D
Define ADRDSEQ.q,AdresdebF.q,AdresFinF.q,Adresdeb.q,delta
; **************** Réalisation du vecteur modulo npp à partir d'une table des nombres premiers des 100 premiers nombres *********
;***** Choix du premier Nb premier pour lequel le vecteur modulo sera appliqué.
;***** pour éviter la génération d'un vesteur trop important nous limiterons ce choix aux 23 premiers nombres premiers soit :2 3 5 7 11 13 17 19 23 29 31
;***** Recherche du modulo < 2*3*5*7*11=2310 éléments du vecteur
SAISIE0:
mess$+"Filtre de réduction des diviseurs"
If Len(mess$)>120
MessageRequester("Erreur","Colonne Div max 2 3 5 7 11 13 17 19 23"+#CR$+"Relancez le prg") ;
End
EndIf
nb$=InputRequester(mess$,"Colonne Div max 2 3 5 7 11 13 17 19 23","5") ;
If Val(nb$)>23
Goto SAISIE0
EndIf
nbs=Val(nb$)
If nbs<1 Or nbs>31
Goto SAISIE0
EndIf
rest.l=nbs%30
If rest=2 Or rest=3 Or rest=5 Or rest=7 Or rest=11 Or rest=13 Or rest=17 Or rest=19 Or rest=23
Else
Goto SAISIE0
EndIf
; NBPFACT=NBS
; FINSAISIE0:
Restore lab_pnbp
i=0
Modulo=1
Repeat
Read.l ELEM
If ELEM<>0
T_modulo(I)=elem
Modulo*elem
i+1
EndIf
Until ELEM=0 Or ELEM=>nbs
ReDim SEQD\TDIF(Modulo+10)
SEQD\MODULO=MODULO
SEQD\NBPFACT=nbs
NBprem=i-1
nbs=ELEM
Dim tcol.colonne(SEQD\MODULO+2)
;*** Recherche des colonnes ayant des nb premiers ***
tcol(0)\prem=2
tcol(1)\prem=2
Tdep.q=ElapsedMilliseconds()
For inb=2 To modulo+1
For inbp=0 To nbprem
If inb % t_modulo(inbp)=0
tcol(inb)\prem=2
EndIf
Next
Next
prem_p=0
PREM_NB_PREM_AV=0
NB_PREM=0
SOM_DIF=0
vecteur$="DIV_"+Str(nbs)+":"+#CRLF$
;****** Recherche des différence entre NB premiers *****
If CreateFile(0,"DIVA_"+Str(nbs)+".PB") ; création d'un nouveau fichier texte...
NBSEQ=0
For inb=2 To modulo+1
; tcol(inb)\nb=inb
If tcol(inb)\prem=0 And inb>nbs
If prem_p=0
prem_p=inb
PREM_NB_PREM_AV=inb
vecteur$+"DATA.A "+Str(inb)+","
SEQD\PREMDIV=inb
NBSEQ+1
Else
NB_PREM+1
If nb_prem % 101=0
If nb_prem % 201=0
PrintN(_n(NB_prem)+_n(prem_p)+_n(tcol(inb)\dif_prec)+_n(som_dif)+_n(ElapsedMilliseconds()-Tdep)+_n(lvecteur))
EndIf
If nb_prem % 5=0 ; ici tous les =101*x c'est avec 5 que l'on obtient le meilleur résultat
vecteur$+Str(inb-prem_p)+#CRLF$
; SEQD\TDIF(NBSEQ-1)=inb-prem_p
SEQD\TDIF(NBSEQ)=inb-prem_p
NBSEQ+1
lvecteur=Len(vecteur$)
WriteString(0,vecteur$) ;
vecteur$="Data.A "
Else
vecteur$+Str(inb-prem_p)+#CRLF$+"Data.A "
; SEQD\TDIF(NBSEQ-1)=inb-prem_p
SEQD\TDIF(NBSEQ)=inb-prem_p
NBSEQ+1
EndIf
tcol(inb)\dif_prec=inb-prem_p
SOM_DIF+(inb-prem_p)
; tcol(prem_p)\Dif_act=inb-prem_p
prem_p=inb
Else
tcol(inb)\dif_prec=inb-prem_p
vecteur$+Str(inb-prem_p)+","
; SEQD\TDIF(NBSEQ-1)=inb-prem_p
SEQD\TDIF(NBSEQ)=inb-prem_p
NBSEQ+1
SOM_DIF+(inb-prem_p)
; tcol(prem_p)\Dif_act=inb-prem_p
prem_p=inb
EndIf
EndIf
EndIf
Next
; tcol(modulo+2)\dif_prec=nb_prem+modulo-(modulo+1)
NB_PREM+1
tcol(modulo+2)\dif_prec=PREM_NB_PREM_AV-1
SEQD\TDIF(NBSEQ)=PREM_NB_PREM_AV-1
SEQD\TDIF(0)=PREM_NB_PREM_AV-1
SEQD\NBSEQ=NBSEQ
ReDim SEQD\TDIF(NBSEQ+2)
; tcol(1)\Dif_act=PREM_NB_PREM_AV-1
; tcol(1)\nb=1
SOM_DIF+(PREM_NB_PREM_AV-1)
rapportq.d=100.0*(modulo-Nb_prem)/modulo
vecteur$+Str(PREM_NB_PREM_AV-1)+",0 ;"+#CRLF$+";; Modulo="+Str(modulo)+" Nb Elements dans vecteur="+Str(NB_prem)+" NBPFACT="+Str(SEQD\NBPFACT)+" Nb sequences="+Str(NBSEQ)+" GAin="+Str(rapportq)+"%"
WriteString(0,vecteur$) ;
CloseFile(0) ; ferme le fichier précédemment ouvert et enregistre les données
PrintN(_n(ElapsedMilliseconds()-Tdep))
RAPPORT.D=modulo/NB_PREM
MessageRequester("C'est tout bon","Somme des nb du vecteur="+_n(SOM_DIF)+#CRLF$+_n(modulo)+#CRLF$+"voir le fichier pour le détail du vecteur"+#CRLF$+"Fichier: "+GetCurrentDirectory()+"DIVA_"+Str(nbs)+".PB"+#CRLF$+"Nomnre d'éléments dans le vecteur="+Str(NB_PREM)+" Rapport="+StrD(RAPPORT))
Else
MessageRequester("Information","Impossible de créer le fichier! DIVA_"+Str(nbs)+".PB")
EndIf
; Adresdeb.l=@SEQD\NBPFACTStructure DIVIS
; NBPFACT.a
; PREMDIV.l
; NBSEQ.l
; MODULO.q
; ; Array TDIF.a(40000000) ;; *** ATTENTION A utiliser avec DATA.A et read.A mais très lent avec p_fact(23) P_fact(19) est préférable remplacer 40 par 2
; Array TDIF.a(40000000)
ADRDSEQ.q=@SEQD
AdresdebF.q=@SEQD\NBPFACT
AdresFinF.q=@SEQD\MODULO+SizeOf(quad)
Adresdeb.q=@SEQD\TDIF(0)
delta=AdresFinF-AdresdebF
If CreateFile(1, "MEMA_"+Str(nbs)+".bin")
WriteData(1,ADRDSEQ ,delta )
; WriteData(1,Adresdebf , 17)
WriteData(1,Adresdeb , SEQD\NBSEQ+1)
CloseFile(1)
Else
MessageRequester("ATTENTION", "Fichier "+ "MEMA_"+Str(nbs)+".bin non créer")
EndIf
;;; Ecriture des 48 colonnes
col$=""
dif$=""
For inb=0 To modulo+1
If tcol(inb)\prem=0
col$+Str(inb)+","
dif$+Str(tcol(inb)\dif_prec)+","
EndIf
Next
PrintN(col$)
PrintN(dif$)
;;; Fin ecriture
PrintN("C'est fini")
Input()
CloseConsole()
DataSection
lab_pnbp:
Data.l 2,3,5,7,11,13,17,19,23,29,31,0
EndDataSection
DataSection
lab_pnbp2:
Data.L 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
Data.L 101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199
Data.L 211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293
Data.L 307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397
Data.L 401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499
Data.L 503,509,521,523,541,547,557,563,569,571,577,587,593,599
Data.L 601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691
Data.L 701,709,719,727,733,739,743,751,757,761,769,773,787,797
Data.L 809,811,821,823,827,829,839,853,857,859,863,877,881,883,887
Data.L 907,911,919,929,937,941,947,953,967,971,977,983,991,997,0
EndDataSection
; ***************** Ci dessous les Nombres premiers pour les 1000 premiers nombres
; 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
; 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
; 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293
; 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397
; 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499
; 503 509 521 523 541 547 557 563 569 571 577 587 593 599
; 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691
; 701 709 719 727 733 739 743 751 757 761 769 773 787 797
; 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887
; 907 911 919 929 937 941 947 953 967 971 977 983 991 997
Code : Tout sélectionner
; algorithme de recherche des nombres PREMIERS par zones
; ATTENTION ENTRE 1E2-1E1 =90 entre 1E3-1E2=900 entre 1E4-1E3=9000 entre 1E12-1E11= 900000000000
;; et entre 2^63 et 2^64 différence 2^63 = 9223372036854775808
; Le nombre 1 n'est pas par convention un nombre premier.
; Tous les nombres premiers >5 se terminent par 1 3 7 ou 9 seulement
; exemple des p_fact(x)
; p_fact(x)--modulo-----------------Nb_occurrences des différences--------Taux-----------Gain
; 3__________6__________________________2_________________________________0,3333_________66,66%
; 5__________30_________________________8_________________________________0,2666_________73,33%
; 7__________210________________________48________________________________0,2285_________77,14%
; 11_________2310_______________________480_______________________________0,2078_________79,22%
; 13_________30030______________________5760______________________________0,1918_________80,81%
; 17_________510510 ____________________92160_____________________________0,18052________81,94%
; 19_________9699690____________________1658880___________________________0,17102________82,89%
; 23_________223092870__________________36495360__________________________0,16358________83,64%
Macro _HHQ (_HHQ,_pr="$")
_PR+RSet(Hex(PeekQ(@_HHQ),#PB_Quad),16,"0")
EndMacro
EnableExplicit
; DisableDebugger
; 2 3 5 7 11 13 17 19 23
Global Dim TABTERMIN.Q(4)
Structure ldec
DIFF.l
IND.l
EndStructure
Structure synchro
StructureUnion
SYNCDEC.ldec
SYNCALP.q
EndStructureUnion
EndStructure
Structure DIVIS
NBPFACT.a
PREMDIV.l
NBSEQ.l
MODULO.q
Array TDIF.a(37000000) ;;
EndStructure
Structure INFOTEMP
NBASE$
NBASE.Q
NBASEHEX$
NBASEDIFB.q
NBASEIND.q
NBASEDIFS.q
NBASERAC.Q
NBASEP.Q
NBASEPHEX$
NBASEPDIF.Q
NBASEPIND.q
NBASEPRAC.q
NPLAGE$
NPLAGE.Q
NPLAGEHEX$
NPLAGEMAX$
NBASEM$
NBASEM.Q
NBASEMHEX$
NBASEMP.Q
NBASEMPHEX$
NBASEMIND.q
NBASEMRAC.Q
; FUTBASE$
; FUTBASED.D
; FUTBASE.q
; FUTBASEHEX$
; ; FUTBASEP.Q
; ; FUTBASEPHEX$
; FUTBASEIND.q
; FUTBASERAC.Q
EndStructure
Structure INFOCALC
NBASE$
NBASE.Q
NBASEHEX$
NBASEDIFB.q
NBASEIND.q
NBASEDIFS.q
NBASERAC.Q
NBASEP.Q
NBASEPHEX$
NBASEPDIF.Q
NBASEPIND.q
NBASEPRAC.q
EndStructure
Global INFOSAISIE.INFOTEMP
Global result$,rest,SEQD.DIVIS,delta_deb.q,NBDIVISIONE.D
Global nbs.l,NBSEQ.l,SEQD.DIVIS,LIMIT$="7FFFFFFFFFFFFFFF",LIMITQ.Q=$7FFFFFFFFFFFFFFF,RACLIM.d=Sqr(LIMITQ)
Define nb$,nb.q,B2DIVIS.q,B2PAS,mess$,quotient.q,ind.l,B1MIN.Q=1E12,pos,B1MIN_DEP.Q,ZONEP.Q,presultat$,resultat$
Define MAX.Q=B1MIN+1E4,nbg$,nbd$,pose.l,t_ind.l,t_col.l,t_ind_dep.l,MAXMAXDIV.q,RAC2.Q,B1MINRAC2.Q,nbseqp,B2IND_MAXDIV,DIF_MAXDIV
Define ind_dep,DIFF,FLAGFIN,IND_NB,CENTM,B2DIVISM,B2INDDD, B2DIVIS$,B2MAXDIV.q,dep_time.q,cent,nbseq_1.q,P_MAXDIV.q,MAXHEX$
Procedure.Q DIVI64_32Q(DIVIDENTE.Q,DIVISEUR.Q)
Protected QUOTIENTS.Q
Global RESTES_.Q ;; impossible de le placer en shared
EnableExplicit
EnableASM
MOV ecx,dword[p.v_DIVISEUR] ;;;; la division euclidienne X=kQ+R avec R<Q nous oblige à utiliser une astuce
XOr EDX,EDX ;;;; pour éviter avec un diviseur trop petit et un dividente trop grand d'avoir un reste de type qword or EDX est de type dword
MOV eax,dword[p.v_DIVIDENTE+4]
DIV ecx
MOV dword[p.v_QUOTIENTS+4],eax
MOV eax,dword[p.v_DIVIDENTE]
DIV ecx
MOV dword[p.v_QUOTIENTS],eax
MOV dword[v_RESTES_],edx
DisableASM
ProcedureReturn QUOTIENTs
DisableExplicit
EndProcedure
Procedure.Q DIVI64_32R(DIVIDENTE.Q,DIVISEUR.Q)
Shared QUOTIENTS_.Q
Protected RESTES_.Q
EnableASM
MOV ecx,dword[p.v_DIVISEUR] ;;;; la division euclidienne X=kQ+R avec R<Q nous oblige à utiliser une astuce
XOr EDX,EDX ;;;; pour éviter avec un diviseur trop petit et un dividente trop grand d'avoir un reste de type qword or EDX est de type dword
MOV eax,dword[p.v_DIVIDENTE+4]
DIV ecx
MOV dword[v_QUOTIENTS_+4],eax
MOV eax,dword[p.v_DIVIDENTE]
DIV ecx
MOV dword[v_QUOTIENTS_],eax
MOV dword[p.v_RESTES_],edx
DisableASM
ProcedureReturn RESTES_
EndProcedure
Procedure PREM_1_3_7_9(NBprem.Q);;;; Répartition des Nb premiers par terminaison 1 3 7 9 ********************
Protected rest10.A
EnableExplicit
Rest10.A=DIVI64_32R(NBPREM,10)
Select REST10
Case 1
TABTERMIN(1)+1
Case 3
TABTERMIN(2)+1
Case 7
TABTERMIN(3)+1
Case 9
TABTERMIN(4)+1
Default
MessageRequester("Attention " , _HHQ(NBPREM,"")+" n'est pas premier ")
EndSelect
DisableExplicit
EndProcedure
Procedure.s choixdiv()
Protected COUR_DIR$,Filtre$,fichier$,Tfichier,fichierp$,leftfich$,RIGHTfich$,deb00.q,deb0.q,ADRDSEQ.q,AdresdebF.q,AdresFinF.q,Adresdeb.q,delta
EnableExplicit
COUR_DIR$ = GetCurrentDirectory()
Filtre$ = "MEMA (MEMA_*.BIN)|MEMA_*.BIN;|Tous les fichiers (*.*)|*.*"
fichier$=OpenFileRequester("Choisissez un fichier MEMA ou annulez", COUR_DIR$+"\MEMA_17.BIN", Filtre$, 0)
fichierp$=UCase(Trim(GetFilePart(fichier$)))
Tfichier=FileSize(Fichier$)
leftfich$=Left(fichierp$,5)
RIGHTfich$=Right(fichierp$,4)
If Tfichier<1 Or Left(fichierp$,5)<>"MEMA_" Or Right(fichierp$,4) <>".BIN"
MessageRequester( "ATTENTION", "fichier vide ou le nom n'est pas conforme "+ _n(Tfichier)+" "+_s(fichierp$))
End
EndIf
; FICHIER$=choixdiv()
deb00.q=ElapsedMilliseconds()
;************************************************************************************************************************************
ADRDSEQ=@SEQD
AdresdebF=@SEQD\NBPFACT
AdresFinF=@SEQD\MODULO+SizeOf(quad)
Adresdeb=@SEQD\TDIF(0)
delta=AdresFinF-AdresdebF
If OpenFile(2,FICHIER$);,#PB_File_SharedRead|#PB_File_NoBuffering)
ReadData(2,ADRDSEQ ,delta)
ReDim SEQD\TDIF(SEQD\NBSEQ+1)
ReadData(2, Adresdeb,SEQD\NBSEQ+1)
CloseFile(2)
EndIf
deb0.q=ElapsedMilliseconds()
delta_deb.q=deb0-deb00
EnableExplicit
EndProcedure
Procedure.q SYNCHRO(NBASYNCHRO.Q)
Protected restd.q,t_ind.q,t_col,ind,INFO.SYNCHRO,t_ind_dep,MODULO.Q
EnableExplicit
MODULO.q=SEQD\MODULO
restd.q=0
EnableASM
MOV ecx,dword[p.v_MODULO] ;;;; la division euclidienne X=kQ+R avec R<Q nous oblige à utiliser une astuce
XOr EDX,EDX ;;;; pour éviter avec un diviseur trop petit et un dividente trop grand d'avoir un reste de type qword or EDX est de type dword
MOV eax,dword[p.v_NBASYNCHRO+4]
DIV ecx
; MOV dword[v_quotientp],eax
MOV eax,dword[p.v_NBASYNCHRO]
DIV ecx
MOV dword[p.v_restd],edx
DisableASM
;
; ; restd=NBASYNCHRO%SEQD\MODULO
t_ind=0
t_col=1
For ind=0 To SEQD\MODULO
If restd<=t_col
t_ind_dep=t_ind
Break
Else
t_col+seqd\TDIF(t_ind)
t_ind+1
EndIf
Next
INFO\SYNCDEC\DIFF=t_col-restd
INFO\SYNCDEC\IND=t_ind_dep
ProcedureReturn info\SYNCALP
DisableExplicit
EndProcedure
Procedure.s HEX2DEC(HEXS.S)
EnableExplicit
Static Dim t_rest.a(1000)
Protected DIVIDENDE$,vald.q,longt,resultat$,DIVIDP$,DIVIDPR$,QUOTP.q,RESTP.q,quotp$,j,ii,DIVIDP.Q,Irest
DIVIDENDE$=LTrim(UCase(HEXS))
vald.q=Val("$"+DIVIDENDE$)
longt=Len(DIVIDENDE$)
If vald>0 And longt<17
resultat$=Str(vald)
Else
Irest=0
DIVIDP$=""
DIVIDPR$=""
quotp$=""
Repeat
For ii=1 To longt
DIVIDP$=DIVIDPR$+Mid(DIVIDENDE$,ii,1)
DIVIDP.Q=Val("$"+DIVIDP$)
; QUOTP.q=DIVIDP/10
; RESTP.q=DIVIDP%10
EnableASM
MOV ax,word [p.v_DIVIDP]
MOV cl,10
; idiv Cl
DIV cl ; utilise moins de cycles machine que idiv
MOV [p.v_QUOTP],al
MOV [p.v_RESTP],AH
DisableASM
DIVIDPR$=Hex(RESTP)
quotp$+Hex(QUOTP)
Next
t_rest(Irest)=RESTP
Irest+1
DIVIDENDE$=QUOTP$
longt=Len(DIVIDENDE$)
DIVIDP$=""
DIVIDPR$=""
quotp$=""
Until Val("$"+ dividende$)=0
For j=Irest-1 To 0 Step-1
resultat$+Str( t_rest(j))
t_rest(j)=0
Next
EndIf
ProcedureReturn resultat$
DisableExplicit
EndProcedure
Procedure.s DEC2HEX(DECI.S)
EnableExplicit
Static Dim t_rest.a(1000)
Protected DIVIDENDE$,vald.q,longt,resultat$,DIVIDP$,DIVIDPR$,QUOTP.q,RESTP.q,quotp$,i,j,ii,DIVIDP.Q,Irest
DIVIDENDE$=UCase(DECI)
longt=Len(DIVIDENDE$)
If Val(DIVIDENDE$)=>0 And longt<20
vald.q=Val(DIVIDENDE$)
resultat$=Hex(vald)
Else
irest=0
DIVIDP$=""
DIVIDPR$=""
quotp$=""
Repeat
For ii=1 To longt
DIVIDP$=DIVIDPR$+Mid(DIVIDENDE$,ii,1)
DIVIDP.Q=Val(DIVIDP$)
; QUOTP.q=DIVIDP/16
; RESTP.q=DIVIDP%16
EnableASM
MOV ax,word [p.v_DIVIDP]
MOV cl,16
; div Cl
DIV Cl ; utilise moins de cycles machine que idiv
MOV [p.v_QUOTP],al
MOV [p.v_RESTP],AH
DisableASM
DIVIDPR$=Str(RESTP)
quotp$+Str(QUOTP)
Next
t_rest(Irest)=RESTP
Irest+1
DIVIDENDE$=QUOTP$
longt=Len(DIVIDENDE$)
DIVIDP$=""
DIVIDPR$=""
quotp$=""
Until Val(dividende$)=0
For j=Irest-1 To 0 Step-1
resultat$+Hex( t_rest(j))
t_rest(j)=0
Next
EndIf
ProcedureReturn resultat$
DisableExplicit
EndProcedure
Procedure CALCUL(_NB.S,*SCALCUL.INFOCALC )
EnableExplicit
; PROCEDURE CALCUL(_NB.S,SCALCUL.INFOCALC )
Static ADR1.q,ADR2.q,ADR3.Q,ADR4.q,FLAG=0
Protected POSE,BASEMIN.q,nbasehex$,lnbh,A1.q,A2.q,NBASE.Q,DIFFB.q,difd.d,limitd.d,K.d,RACK.d,DIVMAX.q,NBASEP.q,SYNCDIVIS.SYNCHRO
Protected MAX_DIV.SYNCHRO,DIVMAXD.d,DIVMAXPD.d,DIVMAXP.q
If Mid(_NB,1,1)="$"
nbasehex$=Right(_NB,Len(_NB)-1)
Else
POSE=FindString(_NB,"E")
If pose>0
BASEMIN.q=ValD(_NB)
nbasehex$=_HHQ(basemin,"")
Else
nbasehex$=dec2hex(_NB)
EndIf
EndIf
; lnbh=len(nbasehex$)
; nbasehex$=ReplaceString(space(16-lnbh)," ","0")+nbasehex$
nbasehex$=Right("0000000000000000"+nbasehex$,16)
If lnbh>16 Or nbasehex$>"FFFFFFFFFFFFFFFE"
INFOSAISIE\nbase$=""
INFOSAISIE\NPLAGE$=""
ProcedureReturn 2
Goto FIN
EndIf
;;;;; recherche d'une racine carré de nb à partir de la différence
A1.q=Val("$"+Mid(nbasehex$,9,16))
A2.q=Val("$"+Mid(nbasehex$,1,8))
; debug _n(A1)+_n(A2)
NBASE.q=0
DIFFB.Q=0
EnableASM ;; ici recherche en cours pour évaluer le plus précisément la racine carré des nombres >2^63-1
MOV eax,dword[p.v_A1]
MOV dword[p.v_NBASE],eax
MOV edx,dword[p.v_A2]
MOV dword [p.v_NBASE+4],edx
SUB eax,dword[v_LIMITQ]
SBB edx,dword[v_LIMITQ+4]
MOV dword[p.v_DIFFB],eax
MOV dword [p.v_DIFFB+4],edx
If nbasehex$>LIMIT$
;;;;; recherche d'une racine carré de nb à partir de la différence
difd.d=DIFFB
limitd.d=limitq
K.d=DIFd/LIMITd ;;;; k est défini sur la plage -1 +1 pour une plage div de +$7FFFFFFFFFFFFFFF à -$7FFFFFFFFFFFFFFF
RACK.D=Sqr(1+K) ;;;; plage de 0 sqr(2)
DIVMAXD.d=RACLIM *RACK
DIVMAX.q=divmaxd ;;limite de recherche des facteurs premiers de la base
Else
DIVMAX=Sqr(Val("$"+nbasehex$))
EndIf
; IF NBASE < SEQD\PREMDIV
SYNCDIVIS\SYNCALP=SYNCHRO(NBASE)
*SCALCUL\NBASEP=NBASE+SYNCDIVIS\SYNCDEC\DIFF
*SCALCUL\NBASEDIFS=SYNCDIVIS\SYNCDEC\DIFF
*SCALCUL\NBASEIND=SYNCDIVIS\SYNCDEC\IND
*SCALCUL\NBASEPHEX$=_HHQ(*SCALCUL\NBASEP,"")
*SCALCUL\NBASE=NBASE
*SCALCUL\NBASE$=_NB
*SCALCUL\NBASEHEX$=nbasehex$
*SCALCUL\NBASERAC=DIVMAX
*SCALCUL\NBASEDIFB=DIFFB
; *SCALCUL\NBASEIND=INDBASE
; *SCALCUL\NBASEP=NBASEP
If NBASE>0 And NBASE<SEQD\PREMDIV
*SCALCUL\NBASEP=SEQD\PREMDIV
EndIf
*SCALCUL\NBASEPHEX$=_HHQ(*SCALCUL\NBASEP,"")
SYNCDIVIS\SYNCALP=SYNCHRO(*SCALCUL\NBASEP)
*SCALCUL\NBASEPDIF=SYNCDIVIS\SYNCDEC\DIFF
*SCALCUL\NBASEPIND=SYNCDIVIS\SYNCDEC\IND
difd.d=SYNCDIVIS\SYNCDEC\DIFF
K.d=DIFd/*SCALCUL\NBASEP ;;;;
RACK.D=Sqr(1+K) ;;;; plage de 0 sqr(2)
DIVMAXPD.d=*SCALCUL\NBASERAC *RACK
DIVMAXP.q=divmaxpd ;;
If divmaxp<4294967296
divmaxp+1
EndIf
*SCALCUL\NBASEPRAC=DIVMAXP
FIN:
DisableExplicit
EndProcedure
Procedure EXTRINFO(NBE$)
Protected pose, basmin.q,nbasehex$,lnbh,A1.q,A2.q,NBASE.Q,DIFFE.Q,difd.d,limitd.d,K.d,RACK.d,DIVMAXD.d,DIVMAX.q,NB$,DIFFB.Q
Static FLAG=0
Shared INF_CAL.INFOCALC, INF_CAL3.INFOCALC
Protected NBl3$,NB_A_TESTER.Q,NB_DE_DIVISEUR_MPAR.Q,NB_DE_DIVISEUR_MAX.d,KEFFICACE.D,LOG2X.d
EnableExplicit
Global T1.Q=ElapsedMilliseconds()
Select FLAG
Case 0
; if INFOSAISIE\nbase$=""
calcul (NBE$,INF_CAL)
CopyMemory(INF_CAL,INFOSAISIE,SizeOf(INFOCALC))
Case 1
; PRiNTN("X PASSAGE "+_n(FLAG)+_s(NBE$))
calcul (NBE$, INF_CAL3)
; calcul (NB$)
INFOSAISIE\NPLAGE$=NBe$
INFOSAISIE\NPLAGE=INF_CAL3\NBASE
INFOSAISIE\NPLAGEHEX$=INF_CAL3\NBASEHEX$
If INFOSAISIE\NPLAGEHEX$>INFOSAISIE\NPLAGEMAX$
ProcedureReturn 3
; goto FIN
EndIf
;********************************** Recherche infos de NBASE MAX ***********************************
INFOSAISIE\NBASEM=INFOSAISIE\NBASE+INFOSAISIE\NPLAGE
INFOSAISIE\NBASEMHEX$=_HHQ(INFOSAISIE\NBASEM,"")
NBl3$="$"+INFOSAISIE\NBASEMHEX$
INFOSAISIE\NBASEM$=NBl3$
If INFOSAISIE\NBASEMHEX$>LIMIT$
A1.q=Val("$"+Mid(INFOSAISIE\NBASEMHEX$,9,16))
A2.q=Val("$"+Mid(INFOSAISIE\NBASEMHEX$,1,8))
NBASE.q=0
DIFFB.Q=0
EnableASM ;; ici recherche en cours pour évaluer le plus précisément la racine carré des nombres >2^63-1
MOV eax,dword[p.v_A1]
MOV dword[p.v_NBASE],eax
MOV edx,dword[p.v_A2]
MOV dword [p.v_NBASE+4],edx
SUB eax,dword[v_LIMITQ]
SBB edx,dword[v_LIMITQ+4]
MOV dword[p.v_DIFFB],eax
MOV dword [p.v_DIFFB+4],edx
;;;;; recherche d'une racine carré de nb à partir de la différence
difd.d=DIFFB
limitd.d=limitq
K.d=DIFd/LIMITd ;;;; k est défini sur la plage -1 +1 pour une plage div de +$7FFFFFFFFFFFFFFF à -$7FFFFFFFFFFFFFFF
RACK.D=Sqr(1+K) ;;;; plage de 0 sqr(2)
DIVMAXD.d=RACLIM *RACK
DIVMAX.q=divmaxd ;;limite de recherche des facteurs premiers de la base
Else
DIVMAX=Sqr(Val("$"+INFOSAISIE\NBASEMHEX$))
EndIf
; INFOSAISIE\NBASEMRAC=DIVMAX+1
INFOSAISIE\NBASEMRAC=DIVMAX
NB_A_TESTER.Q=INFOSAISIE\NPLAGE
NB_DE_DIVISEUR_MPAR.Q=INFOSAISIE\NBASEMRAC/2+INFOSAISIE\NBASEPRAC/2
NB_DE_DIVISEUR_MAX.d=1.00*NB_DE_DIVISEUR_MPAR*NB_A_TESTER
KEFFICACE.D=SEQD\NBSEQ/SEQD\MODULO
LOG2X.d=Log(NB_DE_DIVISEUR_MAX)*Log10(#E)/Log10(2)
; NBDIVISIONE.D=KEFFICACE*NB_DE_DIVISEUR_MAX/LOG10(NB_DE_DIVISEUR_MPAR)
NBDIVISIONE.D=KEFFICACE*NB_DE_DIVISEUR_MAX
; LOG2X.d=log(NB_DE_DIVISEUR_MAX)*log10(#e)/log10(2)
; NBMILIS.D=NBDIVISIONE
; PRINTN("Nombre de divisions max à effectuer :"+strd(NBDIVISIONE,2));;+" Evaluation du temps en ms : "+strd(NBMILIS))
PrintN("Nombre de divisions max à effectuer :"+StrD(NBDIVISIONE,2))
;;;*********** RECXHERCHE DE LA FUTURE RACINE et RACINE*RACINE*************************************
; delta=SEQD\TDIF(INFOSAISIE\NBASEPIND)
; INFOSAISIE\FUTBASERAC=INFOSAISIE\NBASEPRAC+delta
; INFOSAISIE\FUTBASE=INFOSAISIE\FUTBASERAC*INFOSAISIE\FUTBASERAC
Case 2
; PRiNTN("X PASSAGE "+_n(FLAG))
Case 3
; PRiNTN("X PASSAGE "+_n(FLAG))
Case 4
; PRiNTN("X PASSAGE "+_n(FLAG))
EndSelect
; PRiNTN("X PASSAGE "+_n(FLAG)+_s(NBE$))
FLAG+1
; ProcedureReturn 0
; FIN:
; logB1MIN=Log10(B1MIN)
; logmax=Log10(max-B1MIN)
; If logB1MIN+logmax>22
; rmes=MessageRequester(" ATTENTION Temps très long","Oui=>continuez Non=>donnez autre zone",#PB_MessageRequester_YesNo)
; If Rmes = 6 ; le bouton Oui a été choisi (Resultat = 6)
; Else ; le bouton Non a été choisi (Resultat = 7)
; Goto SAISIE2
; EndIf
; EndIf
DisableExplicit
EndProcedure
Procedure SAISIEBASEPLAGE()
Protected mess$,nb$,pos,NBASE$,NPLAGE$,reto.l,NBASE.q,DIFFF.Q,NPLAGEMAX$,logB1MIN.D, logmax.D, rmes,hhqhex$,NBASE2.Q
EnableExplicit
mess$=""
SAISIE2:
mess$+"Base Zone ex: 98765 1E3, $FF875 1E9 ,1E9 1E4"
If Len(mess$)>120
MessageRequester("Erreur Relancez le Prg","Base +Zone à explorer Ex: 98765 +1E3, $FF875 1E9, 1E9 +1E4 "+#CR$+"Relancez le prg") ;
End
EndIf ;;; 7FFFFFFFFFFFFFFF
nb$=UCase(LTrim(InputRequester(mess$,"Base Zone Ex:98765 1E3, $FF875 1E9, 1E9 1E4","$7FFFFFFFFFFFFF00 +1E3")));
pos=FindString(nb$," ")
NBASE$=Trim(Left(nb$,pos))
NPLAGE$=Trim(Right(NB$,Len(nb$)-pos))
reto.l=EXTRINFO(NBASE$)
If retO>0
Goto saisie2
EndIf
;;;;;;************* Recherche de la plage max possible à utiliser *****************
NBASE.q=INFOSAISIE\NBASE
DIFFF.Q=0
MOV eax,$FFFFFFFE
MOV edx,$FFFFFFFF
SUB eax,dword[p.v_NBASE]
SBB edx,dword[p.v_NBASE+4]
MOV dword[p.v_DIFFF],eax
MOV dword [p.v_DIFFF+4],edx
NPLAGEMAX$=_HHQ(DIFFF,"" )
; NPLAGEMAX$=_HHQ(DIFFF,"")
; lnbh=len(NPLAGEMAX$)
; NPLAGEMAX$=ReplaceString(space(16-lnbh)," ","0")+NPLAGEMAX$
INFOSAISIE\NPLAGEMAX$=NPLAGEMAX$
;;;******************************* recherche de la plage à explorer **************************
If EXTRINFO(NPLAGE$)
Goto saisie2
EndIf
INFOSAISIE\NPLAGEMAX$=NPLAGEMAX$
; ProcedureReturn 0
; FIN:
NBASE2.Q=DIVI64_32Q(NBDIVISIONE,10)
logB1MIN=Log10(NBASE2)+1
logmax=Log10(INFOSAISIE\NPLAGE)
If logB1MIN+logmax>15
rmes=MessageRequester(" ATTENTION Temps très long","Oui=>continuez Non=>donnez autre zone",#PB_MessageRequester_YesNo)
If Rmes = 6 ; le bouton Oui a été choisi (Resultat = 6)
Else ; le bouton Non a été choisi (Resultat = 7)
Goto SAISIE2
EndIf
EndIf
DisableExplicit
EndProcedure
EnableExplicit
Define NB_TOT_DIVIS.q,pos1,k,B1MIN$,B1MINPHEX$,B1MINHEX$,MAX_DIV.SYNCHRO,PAS_IND_NB
OpenConsole()
T1.q=ElapsedMilliseconds()
choixdiv()
SAISIEBASEPLAGE()
PrintN("Fin de la mise en place temps="+Str(ElapsedMilliseconds()-T1))
MAX=INFOSAISIE\NBASEM
MAXHEX$=_HHQ(MAX,"")
B1MIN=INFOSAISIE\NBASEP
B1MIN_DEP=B1MIN
resultat$=""
NB_TOT_DIVIS=0
presultat$="02 03 05 07 11 13 17 19 23 29 31"
If INFOSAISIE\NBASE=>0 And INFOSAISIE\NBASE < SEQD\NBPFACT
pos1=FindString(presultat$,Right("0"+Str(INFOSAISIE\NBASE),2))
; pos1=FindString(presultat$,Str(INFOSAISIE\NBASE))
pose=FindString(presultat$,Right("0"+Str(SEQD\NBPFACT),2))+2
resultat$=Trim(Mid(presultat$,pos1,POSE-pos1))
NB_TOT_DIVIS=CountString(resultat$," ")+1
; CreateRegularExpression(0,"[0-9]+"
If CreateRegularExpression(0,"[0-9]+")
Dim TResult$(0)
Nb = ExtractRegularExpression(0,resultat$, TResult$())
For k = 0 To Nb-1
Select Right(Tresult$(k),1)
Case "1"
TABTERMIN(1)+1
Case "2"
TABTERMIN(0)+1
Case "3"
TABTERMIN(2)+1
Case "5"
TABTERMIN(0)+1
Case "7"
TABTERMIN(3)+1
Case "9"
TABTERMIN(4)+1
EndSelect
Next
Else
Debug RegularExpressionError()
EndIf
; NB_TOT_DIVIS=(POSE-POS1)/2
; B1MIN=SEQD\NBPFACT
EndIf
; ******** sysnchronistion des Nombres à tester avec le vecteur des différences ***********
IND_NB=INFOSAISIE\NBASEPIND
B2DIVIS.q=SEQD\PREMDIV
flagfin=0
; B2MAXDIV.q=Pow(B1MIN,0.5)
B2MAXDIV.q=INFOSAISIE\NBASEPRAC ;;;;;******************************************************
; MAXMAXDIV.q=Sqr(MAX) ;;;;;******************************************************
MAXMAXDIV.q=INFOSAISIE\NBASEMRAC ;;;;;******************************************************
; if B2MAXDIV>MAXMAXDIV
; B2MAXDIV=MAXMAXDIV
; endif
PrintN(_n(MAXMAXDIV) +_n(B2MAXDIV))
PrintN(resultat$)
If B1MIN<0
centm=B1MIN/-100
Else
centm=B1MIN/100
EndIf
;;;;; ***************************** Gestion des diviseurs max *********************
MAX_DIV\SYNCALP =SYNCHRO(B2MAXDIV)
B2IND_MAXDIV=MAX_DIV\SYNCDEC\IND
DIF_MAXDIV=MAX_DIV\SYNCDEC\DIFF
P_MAXDIV=B2MAXDIV+DIF_MAXDIV
; B2MAXDIV=P_MAXDIV
; if MAXMAXDIV-B2MAXDIV<>0
; *B2MAXDIV=SYNCHRO(B2MAXDIV)
; B2IND_MAXDIV=*MAXDIV\IND_SYNCHRO
; DIF_MAXDIV=*MAXDIV\DIFF_SYNCRO
; B2MAXDIV+DIF_MAXDIV
;******************************************************************************************************************
;;****** le prochain B2MAXDIV (A+dif)^2=A^2+2*dif*A+dif^2= si A=SQR(X)=RAC donc (RAC^2)=X alors => (RAC+dif)^2= (RAC^2)+dif^2+2*dif*RAC=X+dif+(2*RAC*dif)
;;;********************* X+dif(1+2*RAC)
; RAC2=DIF_MAXDIV *(2*B2MAXDIV+DIF_MAXDIV)
; B1MINRAC2=B1MIN+RAC2
; =Str(B1MIN)+" "
B2DIVISm=0
nbseq_1.q=SEQD\NBSEQ-1
nbseq=SEQD\NBSEQ
nbseqp=nbseq+1
dep_time.q=ElapsedMilliseconds()
; B2PAS=SEQD\TDIF(1)
;;;***************************************************************************************************************************
;;;*************************** Début des 2 boucles pour rechercher les NB premiers dans une zone MIN MAX *****************
;;;***************************************************************************************************************************
;;;***************************************************************************************************************************
;;;** Début de la première boucle avec incrémentation des Nombrss le la zone donnée pour savoir s'ils sont premiers *******
;;;** fin de la boucle jusqu'à Until où l'on teste si le nb après incrémention est toujour dans la zone donnée *******
;;;***************************************************************************************************************************
Repeat
B2INDDD=1
B2PAS=SEQD\TDIF(B2INDDD)
; PRINTN(_NL+_N(B2DIVIS))
;;;***************************************************************************************************************************
;;;***** Début de la deuxième boucle avec incrémentation des diviseurs du premier Nb X au dessus de p_fact(X) *******
;;;*** jusqu'à la racine du Nb à tester *******
;;;***************************************************************************************************************************
;;; Info propre à boucle div=B2
While B2DIVIS<=B2MAXDIV; or FLAGFIN>0
; printn(_n(B2DIVIS)+_n(B2PAS)+_n(idivis))
; ;Le nom de @@: signifie étiquette anonyme,vous pouvez avoir défini un grand nombre d'entre eux dans la source.
; ;Symbole @b(ou l'équivalent @r)le plus proche des références du label précédent anonyme
; ;,symbole @f références plus proche de l'étiquette suivante anonyme.
; ;Ces symboles spéciaux sont insensibles à la casse.
;;******************************* TESTS EN ASM ********************************************************************
;*************************************** Division d'un nombre de 64 bits par un nombre de 32 bits ******************************************
EnableASM
MOV ecx,dword[v_B2DIVIS]
XOr EDX,EDX
MOV eax,dword[v_B1MIN+4]
DIV ecx
; MOV dword[v_quotientp],eax ;;;; Le reste de la division nous suffit
MOV eax,dword[v_B1MIN]
DIV ecx
CMP edx,0
JNZ @f
INC dword [v_FLAGFIN]
Break
!@@:
MOV edx,dword[v_B2PAS]
ADD dword[v_B2DIVIS],edx ; pas de PB l'addition est réalisée en valeur absolue
ADC dword[v_B2DIVIS+4],0 ; pas de PB l'addition est réalisée en valeur absolue
; donc $FFFFFFFF =>4294967295 donc pas de risque de dépassement sqr(pow(2,63)-1))=>3037000499,9760496922867524030306 <4294967295
;********************************************************************************************************************************************************
DisableASM
;********************************************************************************************************************************************************
;********************************************************************************************************************************************************
; ;*********************************** Pour accélerer encore l' algo *******************************
B2INDDD+1
If B2INDDD=nbseqp ;;; inutil de passer en ASM voir ci dessus c'est plus long de près du double en temps sur la zone 9223372036854774807 1000
B2INDDD=1 ;;;;;9223372036854770999
EndIf
B2PAS=SEQD\TDIF(B2INDDD)
EnableASM
;************************************ Pour accélerer encore l' algo vous pouvez décommentez les 5 lignes PB précedentes ******************************
Wend
;;;;*******************************************************************************************************************************************************
;;;; *********************************************** FIN DE LA DEUXIEME BOUCLE DES DIVISEURS *************************************************************
;;;; *********************************************** FIN DE LA DEUXIEME BOUCLE DES DIVISEUR *************************************************************
;;;;******************************************************************************************S*************************************************************
If flagfin=0 And B1MIN<>1
If B1MIN<0
cent=B1MIN/-100
Else
cent=B1MIN/100
EndIf
If centm<>cent
PrintN(result$)
centm=cent
If B1MIN<0
B1MIN$=HEX2DEC(_HHQ(B1MIN,""))
Else
B1MIN$=Str(B1MIN)
EndIf
result$=B1MIN$+" "
Else
If B1MIN<0
B1MIN$=HEX2DEC(_HHQ(B1MIN,""))
Else
B1MIN$=Str(B1MIN)
EndIf
result$+B1MIN$+" "
EndIf
NB_TOT_DIVIS+1
PREM_1_3_7_9(B1MIN) ;;;; R&partition des Nb premiers par terminaison 1 3 7 9 ******************
EndIf
; printn(_NL+_Q(B1MIN)+_s(result$)+_n(FLAGFIN))
flagfin=0
B1MINPHEX$=B1MINHEX$
PAS_IND_NB=seqd\TDIF(ind_nb)
; B1MIN+ seqd\TDIF(ind_nb)
B1MIN+ PAS_IND_NB
B1MINHEX$=_HHQ(B1MIN,"")
;;;*******************************************************************************************************************************************************************
;;; On peut anticiper la prochaine racine différente de celle actuelle (A+1)^2 =A^2+1+2A si A=SQR(X)=RAC donc (RAC^2)=X alors => (RAC+1)^2= (RAC^2)+1+2*RAC=X+1+(2*RAC)
;;; le mini de diff est 2 donc (A+2)^2 =A^2+4+4A si A=SQR(X)=RAC donc (RAC^2)=X alors => (RAC+2)^2= (RAC^2)+4+4*RAC=X+4+(4*RAC);;;*******************************************************************************************************************************************************************
;;; le mini de diff est D donc (A+D)^2 =A^2+D^2+2AD si A=SQR(X)=RAC donc (RAC^2)=X alors => (RAC+D)^2= (RAC^2)+D^2+2D*RAC=X+D^2+(2*D*RAC);;;*******************************************************************************************************************************************************************
;;; cette technique pose des pb pour les nombres premiers à trouver < au premier diviseur
If B1MIN =>B1MINRAC2
If B1MIN > SEQD\PREMDIV ;;;; Valeurs toujours <$7FFFFFFFFFFFFFFF;
; Il faudrait prendre le prochain diviseur dans le vecteur des différences avec la gestion de cet indice B2IND_MAXDIV essai en cours
; RAC2=DIF_MAXDIV*(2*B2MAXDIV+DIF_MAXDIV)
RAC2=2*PAS_IND_NB* B2MAXDIV +(PAS_IND_NB*PAS_IND_NB)
B1MINRAC2=B1MIN+RAC2
B2MAXDIV.q=Sqr(B1MIN)+PAS_IND_NB+1
; B1MINRAC2.Q=B1MIN+(4*B2MAXDIV)+4
Else
RAC2=4* B2MAXDIV +4
B1MINRAC2=B1MIN+RAC2
B2MAXDIV.q=Sqr(B1MIN)+2
EndIf
EndIf
; If B1MIN =>B1MINRAC2 ;;;; Valeurs toujours <$7FFFFFFFFFFFFFFF;;; avec pas mini de 2
; RAC2=4* B2MAXDIV +4
; B1MINRAC2=B1MIN+RAC2
; B2MAXDIV.q=Sqr(B1MIN)+2
; ; B1MINRAC2.Q=B1MIN+(4*B2MAXDIV)+4
; EndIf
; IF B1MINRAC2>0
; printn(_NL+_S(B1MINHEX$)+_s(MAXHEX$)+_n(B2MAXDIV)+_n(B1MINRAC2)+_n(FLAGFIN))
; endif
; If B2DIVIS =>B2MAXDIV
;
; endif
B2DIVIS=SEQD\PREMDIV
ind_nb+1
; if ind_nb>SEQD\NBSEQ-1
If ind_nb>NBSEQ_1
ind_nb=0 ;;; remise à zéro si le cycle des différences est atteint pour incrémentation des nombres susceptibles d'être premiers
EndIf
; printn(_NL+_S(B1MINHEX$)+_s(MAXHEX$)+_n(B2MAXDIV)+_s(result$)+_n(FLAGFIN)+_n(CENTM)+_n(CENT))
; PrintN(_NL+_S(B1MINHEX$)+_s(MAXHEX$)+_n(B2MAXDIV)+_n(B1MINRAC2)+_n(B2PAS)+_n(FLAGFIN))
If B1MINHEX$<B1MINPhex$
; printn(_NL+_s(B1MINHEX$)+_s(MAXhex$)+_n(B2MAXDIV))
B1MINHEX$=MAXHEX$
EndIf
; paspas=seqd\TDIF(ind_nb)
; printn(_s(B1MINHEX$)+_s(MAXhex$)+_n(B2MAXDIV)+_n(paspas))
Until B1MINHEX$=>MAXHEX$ ;;; Or B1MIN<0 ;;Si vous n'allez pas aux confins de la machine =$7FFFFFFFFFFFFFFF ;;; = 9223372036854775807 valeur max positive en ..q.
;; Vous pouvez retirer (or B1MIN<0) ou dépassement de $7FFFFFFFFFFFFFFF
;;;;***********************************************************************************************************************************************************
;;;; *********************************************** FIN DE LA PREMIERE BOUCLE DES Nb à TESTER **************************************************************
;;;; *********************************************** FIN DE LA DEUXIEME BOUCLE DES Nb à TESTER *************************************************************
;;;;***********************************************************************************************************************************************************
PrintN(result$)
; PrintN( "Nombre Minimal = "+Str(INFOSAISIE\NBASE)+" Nombre Maximal = "+Str(MAX))
PrintN( "Nombre Minimal = "+HEX2DEC(_HHQ(INFOSAISIE\NBASE,""))+" Nombre Maximal = "+HEX2DEC(_HHQ(MAX,"")))
PrintN("Nombre d'éléments du vecteur =:"+Str(SEQD\NBSEQ)+" temps de préparation ="+Str(delta_deb))
PrintN("Temps millisecondes ="+Str(ElapsedMilliseconds()-dep_time))
PrintN("Nombre de nb premiers ="+Str(NB_TOT_DIVIS)+" Nb de divisions /miliseconde = "+StrD(NBDIVISIONE/(ElapsedMilliseconds()-dep_time)))
Resultat$=""
For K=1 To 4
Select K
Case 1
resultat$="Termine PAR 1="+Str(TABTERMIN(1))
Case 2
resultat$+" PAR 3="+Str(TABTERMIN(2))
Case 3
resultat$+" PAR 7="+Str(TABTERMIN(3))
Case 4
resultat$+" PAR 9="+Str(TABTERMIN(4))
EndSelect
Next
resultat$+ " PAR 2 ET 5 ="+Str(TABTERMIN(0))
PrintN(resultat$)
PrintN("C'est fini")
Input()
CloseConsole()
; ***************** Ci dessous les Nombres premiers pour les 1000 premiers nombres
; 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
; 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
; 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293
; 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397
; 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499
; 503 509 521 523 541 547 557 563 569 571 577 587 593 599
; 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691
; 701 709 719 727 733 739 743 751 757 761 769 773 787 797
; 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887
; 907 911 919 929 937 941 947 953 967 971 977 983 991 997
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Re: Nombres premiers : vérification à plusieurs
Bonjour Papipp,
merci pour ces codes, ici, ça "gonfle" de données. Sur un petit X64, c'est paradoxal d'avoir posté mon code plus haut, qui est réglé au ralenti.
Tu indiques que ton 1er code est indispensable pour le exécuter le 2nd code. J'ai du mal à voir un détail dedans car les fenêtres de code sont petites.
Car, tu as raison : mathématiquement, il me semble aussi très difficile de chercher des nombres 1ers dans une zone arbitraire, sans recourir aux p-factorielles.
Les gaps (que tu appelles les "différences") récoltés dans le domaine d'une p-factorielle servent de masque. Mais, je crois que c'est en fin 2015, dans la (longue) discussion avec fweil, j'avais parlé d'un décalage de ce masque. Et j'avais évoqué les chenilles d'un char, pour visualiser le mouvement de ce décalage. Si on ne fait pas ce décalage, on se retrouve possiblement avec des nombres premiers qui sont considérés comme multiples, et vice-versa.
Ainsi, on peut donner un résultat, comme je peux dire l'exemple suivant :
Le 28 203 747 ième nombre premier est 537 092 411.
À coup sûr, tout le monde peut vérifier, et éventuellement me dire que j'ai raison. Mais, ça n'implique pas que ma liste de nombres premiers depuis 2 jusqu'à 537 092 411, est exacte : elle peut être fausse.
Un mauvais décalage du "masque" que l'on prépare préalablement interchange des places de nombres possiblement premiers avec des places de nombres multiples (et sournoisement vice-versa).
Pour résumer, on peut voir que je ne crible pas, et c'est ainsi que j'avais trouvé l'existence de ce décalage. Je vérifie par divisions seulement.
Comment apréhendes-tu ce décalage dans tes codes ? C'est ce détail que je n'arrive pas à trouver facilement. Est-ce la fonction SYNCHRO() ?
Est-ce la recherche de la racine suivante ? (Le décalage étant lié au carré du nombre choisi "pour" p-fact(choisi) multiplié (et modulé, comme la chenille d'un char ramène au début ce qui dépasse à la fin) par le rang K tel que le départ est K * p-fact(choisi) )
merci pour ces codes, ici, ça "gonfle" de données. Sur un petit X64, c'est paradoxal d'avoir posté mon code plus haut, qui est réglé au ralenti.
Tu indiques que ton 1er code est indispensable pour le exécuter le 2nd code. J'ai du mal à voir un détail dedans car les fenêtres de code sont petites.
Car, tu as raison : mathématiquement, il me semble aussi très difficile de chercher des nombres 1ers dans une zone arbitraire, sans recourir aux p-factorielles.
Les gaps (que tu appelles les "différences") récoltés dans le domaine d'une p-factorielle servent de masque. Mais, je crois que c'est en fin 2015, dans la (longue) discussion avec fweil, j'avais parlé d'un décalage de ce masque. Et j'avais évoqué les chenilles d'un char, pour visualiser le mouvement de ce décalage. Si on ne fait pas ce décalage, on se retrouve possiblement avec des nombres premiers qui sont considérés comme multiples, et vice-versa.
Ainsi, on peut donner un résultat, comme je peux dire l'exemple suivant :
Le 28 203 747 ième nombre premier est 537 092 411.
À coup sûr, tout le monde peut vérifier, et éventuellement me dire que j'ai raison. Mais, ça n'implique pas que ma liste de nombres premiers depuis 2 jusqu'à 537 092 411, est exacte : elle peut être fausse.
Un mauvais décalage du "masque" que l'on prépare préalablement interchange des places de nombres possiblement premiers avec des places de nombres multiples (et sournoisement vice-versa).
Pour résumer, on peut voir que je ne crible pas, et c'est ainsi que j'avais trouvé l'existence de ce décalage. Je vérifie par divisions seulement.
Comment apréhendes-tu ce décalage dans tes codes ? C'est ce détail que je n'arrive pas à trouver facilement. Est-ce la fonction SYNCHRO() ?
Est-ce la recherche de la racine suivante ? (Le décalage étant lié au carré du nombre choisi "pour" p-fact(choisi) multiplié (et modulé, comme la chenille d'un char ramène au début ce qui dépasse à la fin) par le rang K tel que le départ est K * p-fact(choisi) )
Re: Nombres premiers : vérification à plusieurs
Et comme "tout savoir, et rien donner" c'est pas cool
et que j'avais "promis" une illustration sur les écart (ou "gaps" ou "différences") entre nombres 1ers successifs,
et grâce à l'aide de ArS,
voici l'image :
et que j'avais "promis" une illustration sur les écart (ou "gaps" ou "différences") entre nombres 1ers successifs,
et grâce à l'aide de ArS,
voici l'image :
Re: Nombres premiers : vérification à plusieurs
je ne sais pas copier correctement un fichier, avec des tableaux et des colonnes colorées, dans ce forum.
Voir la solution ci-dessous
A+
Voir la solution ci-dessous
A+
Dernière modification par PAPIPP le mer. 10/août/2022 9:28, modifié 1 fois.
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Re: Nombres premiers : vérification à plusieurs
J'ai réussi à transposer le fichier *.doc en *.jpeg
C'est bien la procédure SYNCHRO() qui permet de savoir à quelle position dans la table on doit commencer.
L'explication est donnée dans le texte ci-dessus ou son résumé ci-dessous.
Principe de la procédure synchro()
Pour définir une zone il nous faut un point de départ et un point d'arrivée.
Seul le point de départ nous intéresse ici.
Ce que nous savons ou connaissons :
1) P_fact(x) le prg peut travailler avec l’une ou l’autre des tables des différences.
Or x est connu ainsi que la première colonne de la matrice d’origine qui est devenue fantôme ici car elle ne sert pas à calculer les nombres premiers.
2) Le numéro de la première colonne utile, est placé dans la table des différences (c'est le cas ici) mais on peut le recalculer)
3) Nous pouvons connaitre la colonne de la matrice fantôme du point de départ.
C’est le reste de la division du point de départ par p_fact(x).
4) Donc maintenant à partir de la table des différences et du numéro de la première colonne.
On peut reconstituer la première ligne de la matrice fantôme.
Et ainsi connaitre la colonne de la table des différences dont le numéro est juste supérieur au numéro de la colonne du point de départ.
A+
C'est bien la procédure SYNCHRO() qui permet de savoir à quelle position dans la table on doit commencer.
L'explication est donnée dans le texte ci-dessus ou son résumé ci-dessous.
Principe de la procédure synchro()
Pour définir une zone il nous faut un point de départ et un point d'arrivée.
Seul le point de départ nous intéresse ici.
Ce que nous savons ou connaissons :
1) P_fact(x) le prg peut travailler avec l’une ou l’autre des tables des différences.
Or x est connu ainsi que la première colonne de la matrice d’origine qui est devenue fantôme ici car elle ne sert pas à calculer les nombres premiers.
2) Le numéro de la première colonne utile, est placé dans la table des différences (c'est le cas ici) mais on peut le recalculer)
3) Nous pouvons connaitre la colonne de la matrice fantôme du point de départ.
C’est le reste de la division du point de départ par p_fact(x).
4) Donc maintenant à partir de la table des différences et du numéro de la première colonne.
On peut reconstituer la première ligne de la matrice fantôme.
Et ainsi connaitre la colonne de la table des différences dont le numéro est juste supérieur au numéro de la colonne du point de départ.
A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Re: Nombres premiers : vérification à plusieurs
Salut PAPIPP,
je vais regarder ça de près quand j'ai le temps. Je vais en gagner en regardant ton travail. J'avais réussi déjà. Je voulais automatiser cette "synchro". Mais il y avait toujours un bug de pas grand chose qui venait se greffer : il fallait programmer manuellement pour être certain de son décalage, et les p-factorielles, ça grandit vite.
Le gain n'est pas en temps pour moi, mais en mémoire. Là, je ne parviens pas à descendre en-dessous de 300 mégaoctets pour la taille du fichier contenant tous les nombres premiers jusqu'à 4 milliards. Donc, merci pour le rappel pratique.
En prog, je suis sur une suite numérique complètement déconcertante. Je posterai le code. J'essaie de la compresser, mais les gaps entre premiers c'est comme un langage sans superflu. Ça tend basiquement à conjecturer ceci :
On a une règle 1 :
à partir de 2 inclu, il n'y a qu'une seule fois la différence de 1 entre 2 nombres premiers consécutifs, et c'est entre 2 et 3 inclus.
On a une règle 2 :
à partir de 3 inclu, il n'y a qu'une seule fois le couple de différences {+2; +2} entre 3 nombres premiers consécutifs, et c'est entre 3 et 7 inclus.
Je conjecture la règle 3 :
à partir de 5 inclu, il n'y a qu'une seule fois le triplet de couples de différences {+2; +4}, entre 7 nombres premiers consécutifs, et c'est entre 5 et 23.
J'ai aussi remarqué que le calcul de la formule de Riemann zeta(x) quand x = 2, c'est seulement par le crible d'Eratosthène qu'il est résolvable partiellement.
J'ai enfin remarqué (peut-être connais-tu ça, ailleurs que de mon origine écrite en 2015) que
(soit a et b, deux nombres premiers consécutifs)
On a :
primoFact(a) + [sumFusion(primoDiff(a)/2) - 1]*b = c
Et je conjecture que c est un (grand) nombre premier.
(avec primoDiff(7) = 4, etc...
et sumFusion(a) le nombre de ressources en demi-gaps (=primoDiff(x)/2) de la règle 3 (conjecture décrite plus haut) utilisées dans le gap (b - a)
C'est sumFusion(x) la suite numérique déconcertante dont je parle plus haut.
C'est une sorte de division tordue comme un théorème de Shadok qui a deux caractéristiques :
- on divise non pas par un nombre mais par un couple de nombres
- on doit prendre en compte le restant de la division précédente pour choisir le diviseur.
Exemple au pif (retenue nulle)Et bien, après 43 millions de nombres premiers non compressée et une mémoire saturée, je n'ai eu que des résultats possibles ! Pas une seule "division" impossible !! Déconcertant...
je vais regarder ça de près quand j'ai le temps. Je vais en gagner en regardant ton travail. J'avais réussi déjà. Je voulais automatiser cette "synchro". Mais il y avait toujours un bug de pas grand chose qui venait se greffer : il fallait programmer manuellement pour être certain de son décalage, et les p-factorielles, ça grandit vite.
Le gain n'est pas en temps pour moi, mais en mémoire. Là, je ne parviens pas à descendre en-dessous de 300 mégaoctets pour la taille du fichier contenant tous les nombres premiers jusqu'à 4 milliards. Donc, merci pour le rappel pratique.
En prog, je suis sur une suite numérique complètement déconcertante. Je posterai le code. J'essaie de la compresser, mais les gaps entre premiers c'est comme un langage sans superflu. Ça tend basiquement à conjecturer ceci :
On a une règle 1 :
à partir de 2 inclu, il n'y a qu'une seule fois la différence de 1 entre 2 nombres premiers consécutifs, et c'est entre 2 et 3 inclus.
On a une règle 2 :
à partir de 3 inclu, il n'y a qu'une seule fois le couple de différences {+2; +2} entre 3 nombres premiers consécutifs, et c'est entre 3 et 7 inclus.
Je conjecture la règle 3 :
à partir de 5 inclu, il n'y a qu'une seule fois le triplet de couples de différences {+2; +4}, entre 7 nombres premiers consécutifs, et c'est entre 5 et 23.
J'ai aussi remarqué que le calcul de la formule de Riemann zeta(x) quand x = 2, c'est seulement par le crible d'Eratosthène qu'il est résolvable partiellement.
J'ai enfin remarqué (peut-être connais-tu ça, ailleurs que de mon origine écrite en 2015) que
(soit a et b, deux nombres premiers consécutifs)
On a :
primoFact(a) + [sumFusion(primoDiff(a)/2) - 1]*b = c
Et je conjecture que c est un (grand) nombre premier.
(avec primoDiff(7) = 4, etc...
et sumFusion(a) le nombre de ressources en demi-gaps (=primoDiff(x)/2) de la règle 3 (conjecture décrite plus haut) utilisées dans le gap (b - a)
C'est sumFusion(x) la suite numérique déconcertante dont je parle plus haut.
C'est une sorte de division tordue comme un théorème de Shadok qui a deux caractéristiques :
- on divise non pas par un nombre mais par un couple de nombres
- on doit prendre en compte le restant de la division précédente pour choisir le diviseur.
Exemple au pif (retenue nulle)
Code : Tout sélectionner
x sumFusion(x)
1 1
2 division par retenue sollicitée nulle (résultat impossible)
3 2
4 3
5 division par retenue sollicitée nulle (résultat impossible)
6 4
7 5
8 division par retenue sollicitée nulle (résultat impossible)
9 6
10 7
11 division par retenue sollicitée nulle (résultat impossible)
12 8
13 9
etc...