Discussion:
Le calcul de la racine carré... pour des nuls :)
(trop ancien pour répondre)
Thierry Loiseau
2024-11-06 20:09:02 UTC
Permalink
Bonsoir,

Vu sur Facebook une démonstration unique en son genre :
---------------------------------------------------------------------
(nota bene : je me contenterai de signer le symbole racine carrée par
la lettre V)
---------------------------------------------------------------------

*********************************************************************
Pour trouver la valeur d'une racine carrée d'un nombre, il fau(drai)t
seulement improviser cela :
*********************************************************************
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Bingo ! Si fasiladoré ! V[64] = 6 + 4 = 8...

Par contre, bien vu pour les exemples

:)

<https://www.facebook.com/photo/?fbid=496784976458835&set=pcb.496785093125490>
--
* * __*__ *
* * * -----oOOo--- O ---oOOo------- * *
http://astrophoto.free.fr *
* * -------- oOOo oOOo ---------- *
Olivier Miakinen
2024-11-06 22:07:24 UTC
Permalink
Bonjour,
Post by Thierry Loiseau
---------------------------------------------------------------------
(nota bene : je me contenterai de signer le symbole racine carrée par
la lettre V)
---------------------------------------------------------------------
Pssst !
<https://www.miakinen.net/vrac/copicol/index>
√9 = ∛27 = ∜81 = 3
Post by Thierry Loiseau
*********************************************************************
Pour trouver la valeur d'une racine carrée d'un nombre, il fau(drai)t
*********************************************************************
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Ça c'est amusant. Je suppose qu'il a listé tous les exemples de moins de
six chiffres, mais cela pose deux questions :

1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?

2) Y a-t-il un équivalent avec les racines cubiques, les racines quatrièmes,
et ainsi de suite ?
Post by Thierry Loiseau
Bingo ! Si fasiladoré ! V[64] = 6 + 4 = 8...
Oui, évidemment. :-D
Post by Thierry Loiseau
Par contre, bien vu pour les exemples
[OUI]
--
Olivier Miakinen
efji
2024-11-06 22:45:43 UTC
Permalink
Post by Olivier Miakinen
Post by Thierry Loiseau
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Ça c'est amusant. Je suppose qu'il a listé tous les exemples de moins de
1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
533170 284270248900
538461 289940248521
609687 371718237969
643357 413908229449
648648 420744227904
670033 448944221089
681318 464194217124
791505 626480165025
812890 660790152100
818181 669420148761
851851 725650126201
857143 734694122449
961038 923594037444
994708 989444005264
999999 999998000001

Il y a tous les (10^n)-1 déjà, et puis aussi les 5*(1+10^{n+1})*10^n.
Donc une infinité.
--
F.J.
Julien Arlandis
2024-11-06 22:54:52 UTC
Permalink
Post by efji
Post by Olivier Miakinen
Post by Thierry Loiseau
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Ça c'est amusant. Je suppose qu'il a listé tous les exemples de moins de
1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
533170 284270248900
538461 289940248521
609687 371718237969
643357 413908229449
648648 420744227904
670033 448944221089
681318 464194217124
791505 626480165025
812890 660790152100
818181 669420148761
851851 725650126201
857143 734694122449
961038 923594037444
994708 989444005264
999999 999998000001
Il y a tous les (10^n)-1 déjà, et puis aussi les 5*(1+10^{n+1})*10^n.
Donc une infinité.
Peut on dire que celui qui a découvert cette propriété a une infinité
de fois raison ?
Olivier Miakinen
2024-11-07 00:56:37 UTC
Permalink
Post by Olivier Miakinen
1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?
[quelques dizaines d'exemples]
Il y a tous les (10^n)-1 déjà,
Oui, comme 9, 99, 999, 9999, etc.
et puis aussi les 5*(1+10^{n+1})*10^n.
Comme 55, 5050, 500500, etc.

Il y a aussi les 5*(-1+10^{n+1})*10^n

Comme 45, 4950, 499500, etc.
Donc une infinité.
De fait, oui. Merci !
--
Olivier Miakinen
Thierry Loiseau
2024-11-07 16:16:22 UTC
Permalink
Post by efji
Post by Olivier Miakinen
Post by Thierry Loiseau
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Ça c'est amusant. Je suppose qu'il a listé tous les exemples de moins de
de moins de _sept_ chiffres
Post by efji
Post by Olivier Miakinen
1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
533170 284270248900
538461 289940248521
609687 371718237969
643357 413908229449
648648 420744227904
670033 448944221089
681318 464194217124
791505 626480165025
812890 660790152100
818181 669420148761
851851 725650126201
857143 734694122449
961038 923594037444
994708 989444005264
999999 999998000001
Il y a tous les (10^n)-1 déjà, et puis aussi les 5*(1+10^{n+1})*10^n.
Donc une infinité.
*Bravo* ! Je ne sais pas comment vous avez établi ces formules...

De mon côté, je m'apprêtais à faire un programme (en JavaScript) pour
trouver les valeurs adequats :-)

*** tous les (10^n)-1 ***

10^0 - 1 = 0 => 0
10^1 - 1 = 9 => 81
10^2 - 1 = 99 => 9801
10^3 - 1 = 999 => 998001

etc.

*** 5*(1+10^{n+1})*10^n ***

0 : 5*(1+10^{0+1})*10^0 => 5*(11)*1 => 3025
1 : 5*(1+10^{1+1})*10^1 => 5*(101)*10 => 5050
2 : 5*(1+10^{2+1})*10^2 => 5*(1001)*100 => 500500
3 : 5*(1+10^{3+1})*10^3 => 5*(10001)*1000 => 50005000

etc.

Grand bravo !!!
--
* * __*__ *
* * * -----oOOo--- O ---oOOo------- * *
http://astrophoto.free.fr *
* * -------- oOOo oOOo ---------- *
efji
2024-11-07 17:03:46 UTC
Permalink
Post by Thierry Loiseau
Post by efji
Post by Olivier Miakinen
Post by Thierry Loiseau
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Ça c'est amusant. Je suppose qu'il a listé tous les exemples de moins de
de moins de _sept_ chiffres
Post by efji
Post by Olivier Miakinen
1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
533170 284270248900
538461 289940248521
609687 371718237969
643357 413908229449
648648 420744227904
670033 448944221089
681318 464194217124
791505 626480165025
812890 660790152100
818181 669420148761
851851 725650126201
857143 734694122449
961038 923594037444
994708 989444005264
999999 999998000001
Il y a tous les (10^n)-1 déjà, et puis aussi les 5*(1+10^{n+1})*10^n.
Donc une infinité.
*Bravo* ! Je ne sais pas comment vous avez établi ces formules...
Pas de mystère. J'ai fait un programme bêtasson et j'ai remarqué qu'il y
avait 999, 9999, 99999, 999999 qui marchaient, et puis 5050, 500500 etc.
Ensuite c'est facile à montrer.
Post by Thierry Loiseau
De mon côté, je m'apprêtais à faire un programme (en JavaScript) pour
trouver les valeurs adequats :-)
Essayez mais à mon avis en javascript vous y êtes encore la semaine
prochaine pour aller jusqu'à 10^13 avec un langage interprété. Attention
aussi aux entiers : par défaut les entiers 32 bits ne dépassent pas
2x10^9. Il faut utiliser des 64 bits, je ne sais pas si ça existe en
javascript.
--
F.J.
Olivier Miakinen
2024-11-08 09:01:39 UTC
Permalink
Post by efji
Post by Thierry Loiseau
*Bravo* ! Je ne sais pas comment vous avez établi ces formules...
Pas de mystère. J'ai fait un programme bêtasson et j'ai remarqué qu'il y
avait 999, 9999, 99999, 999999 qui marchaient, et puis 5050, 500500 etc.
Ensuite c'est facile à montrer.
Oui.
Post by efji
Post by Thierry Loiseau
De mon côté, je m'apprêtais à faire un programme (en JavaScript) pour
trouver les valeurs adequats :-)
Essayez mais à mon avis en javascript vous y êtes encore la semaine
prochaine pour aller jusqu'à 10^13 avec un langage interprété. Attention
aussi aux entiers : par défaut les entiers 32 bits ne dépassent pas
2x10^9. Il faut utiliser des 64 bits, je ne sais pas si ça existe en
javascript.
Si je me rappelle bien, JavaScript représente tous les nombres sous la forme
IEEE754 avec 64 bits, et en particulier il peut représenter de façon exacte
tous les nombres entiers jusqu'à 2^53 = 9 007 199 254 740 992 (et même tous
les nombres entiers de −2^53 à +2^53).

Après ça ne marche plus parce que 2^53 + 1 n'est pas représentable. Le nombre
représentable suivant est 2^53 + 2.
--
Olivier Miakinen
efji
2024-11-08 10:14:01 UTC
Permalink
Post by Olivier Miakinen
Post by efji
Post by Thierry Loiseau
*Bravo* ! Je ne sais pas comment vous avez établi ces formules...
Pas de mystère. J'ai fait un programme bêtasson et j'ai remarqué qu'il y
avait 999, 9999, 99999, 999999 qui marchaient, et puis 5050, 500500 etc.
Ensuite c'est facile à montrer.
Oui.
Post by efji
Post by Thierry Loiseau
De mon côté, je m'apprêtais à faire un programme (en JavaScript) pour
trouver les valeurs adequats :-)
Essayez mais à mon avis en javascript vous y êtes encore la semaine
prochaine pour aller jusqu'à 10^13 avec un langage interprété. Attention
aussi aux entiers : par défaut les entiers 32 bits ne dépassent pas
2x10^9. Il faut utiliser des 64 bits, je ne sais pas si ça existe en
javascript.
Si je me rappelle bien, JavaScript représente tous les nombres sous la forme
IEEE754 avec 64 bits, et en particulier il peut représenter de façon exacte
tous les nombres entiers jusqu'à 2^53 = 9 007 199 254 740 992 (et même tous
les nombres entiers de −2^53 à +2^53).
Après ça ne marche plus parce que 2^53 + 1 n'est pas représentable. Le nombre
représentable suivant est 2^53 + 2.
En fait, je viens de le découvrir car ce langage m'est totalement
étranger, il n'y a pas d'entiers en javascript :) Il n'utilise que des
flottants de 64 bits. Il y a vraiment des informaticiens bizarres sur
cette planète pour penser à des choses pareilles...

Du coup je me demande si c'est vraiment possible de faire ce programme
pour des grandes valeurs en javascript, à cause des erreurs d'arrondis.
Pour des paires de nombres entiers à k chiffres (n,p) il s'agit de
calculer (n+p)^2 et de le comparer à (p+nx10^k). Pour une paire qui
marche, il n'est pas du tout évident que le calcul en flottant donne
l'égalité. Il doit probablement falloir utiliser un test à epsilon près
pour que ça marche.

Pour les entiers 64 bit, les bornes des valeurs accessibles sont −2^63+1
et +2^63-1 (et pas 2^53). Il y a un bit de signe et 63 bits pour la
valeur absolue du nombre.

Pour les réels c'est plus compliqué: il y a un bit de signe, 11 bits
d'exposant, et donc 52 bits de mantisse. Donc si on fait un calcul sur
des entiers on ne peut pas espérer dépasser 10^52.
--
F.J.
Olivier Miakinen
2024-11-08 10:44:59 UTC
Permalink
Post by efji
Post by Olivier Miakinen
Si je me rappelle bien, JavaScript représente tous les nombres sous la forme
IEEE754 avec 64 bits, et en particulier il peut représenter de façon exacte
tous les nombres entiers jusqu'à 2^53 = 9 007 199 254 740 992 (et même tous
les nombres entiers de −2^53 à +2^53).
Après ça ne marche plus parce que 2^53 + 1 n'est pas représentable. Le nombre
représentable suivant est 2^53 + 2.
En fait, je viens de le découvrir car ce langage m'est totalement
étranger, il n'y a pas d'entiers en javascript :) Il n'utilise que des
flottants de 64 bits. Il y a vraiment des informaticiens bizarres sur
cette planète pour penser à des choses pareilles...
:-D
Post by efji
Du coup je me demande si c'est vraiment possible de faire ce programme
pour des grandes valeurs en javascript, à cause des erreurs d'arrondis.
Comme je le disais, il n'y a aucune erreur d'arrondi possible pour les
entiers compris entre −9 007 199 254 740 992 et +9 007 199 254 740 992
car ils sont tous représentés de façon exacte. C'est en dehors de ces
bornes que les problèmes commencent. Et aucun test « à epsilon près » ne
peut résoudre ces problème, car entre 2^53 et 2^54 seuls les nombres pairs
existent. Puis entre 2^54 et 2^55 seuls les multiples de 4, et ainsi de
suite.
--
Olivier Miakinen
efji
2024-11-08 11:03:53 UTC
Permalink
Post by Olivier Miakinen
Post by efji
Post by Olivier Miakinen
Si je me rappelle bien, JavaScript représente tous les nombres sous la forme
IEEE754 avec 64 bits, et en particulier il peut représenter de façon exacte
tous les nombres entiers jusqu'à 2^53 = 9 007 199 254 740 992 (et même tous
les nombres entiers de −2^53 à +2^53).
Après ça ne marche plus parce que 2^53 + 1 n'est pas représentable. Le nombre
représentable suivant est 2^53 + 2.
En fait, je viens de le découvrir car ce langage m'est totalement
étranger, il n'y a pas d'entiers en javascript :) Il n'utilise que des
flottants de 64 bits. Il y a vraiment des informaticiens bizarres sur
cette planète pour penser à des choses pareilles...
:-D
Post by efji
Du coup je me demande si c'est vraiment possible de faire ce programme
pour des grandes valeurs en javascript, à cause des erreurs d'arrondis.
Comme je le disais, il n'y a aucune erreur d'arrondi possible pour les
entiers compris entre −9 007 199 254 740 992 et +9 007 199 254 740 992
car ils sont tous représentés de façon exacte. C'est en dehors de ces
bornes que les problèmes commencent. Et aucun test « à epsilon près » ne
peut résoudre ces problème, car entre 2^53 et 2^54 seuls les nombres pairs
existent. Puis entre 2^54 et 2^55 seuls les multiples de 4, et ainsi de
suite.
Oui bien sûr, au delà de la taille de la mantisse c'est mort.
Mais en dessous en effet ça devrait passer, à condition qu'aucun calcul
intermédiaire ne dépasse la mantisse.
--
F.J.
Samuel Devulder
2024-11-08 23:42:41 UTC
Permalink
Post by efji
En fait, je viens de le découvrir car ce langage m'est totalement
étranger, il n'y a pas d'entiers en javascript 🙂 Il n'utilise que des
flottants de 64 bits. Il y a vraiment des informaticiens bizarres sur
cette planète pour penser à des choses pareilles...
Lua fait pareil et avec les processeurs modernes ca n'est pas
spécialement pénalisant (FPU rapides).

https://www.lua.org/pil/2.3.html

sam.
efji
2024-11-09 11:16:43 UTC
Permalink
Post by Samuel Devulder
Post by efji
En fait, je viens de le découvrir car ce langage m'est totalement
étranger, il n'y a pas d'entiers en javascript 🙂 Il n'utilise que des
flottants de 64 bits. Il y a vraiment des informaticiens bizarres sur
cette planète pour penser à des choses pareilles...
Lua fait pareil et avec les processeurs modernes ca n'est pas
spécialement pénalisant (FPU rapides).
https://www.lua.org/pil/2.3.html
sam.
En effet, ça peut se concevoir, même si c'est perturbant pour un vieux
comme moi. J'aurais du mal à prendre des indices de tableaux comme des
nombres réels, mais on doit pouvoir s'habituer. Le truc embêtant c'est
qu'on perd toute la partie "exposant" du codage : en 64 bits la limite
est 2^53 = 9x10^15 au lieu de 2^63 = 9.2x10^18, on peut s'en contenter,
quoiqu'en adressage il ne soit pas impossible qu'on arrive rapidement à
cette valeur: 9x10^15 c'est 9000 terabits, soient 1000 TB. On y est presque.

En 32 bits c'est impossible de faire ça car pour le plus grand entier on
passerait de 2^31=2x10^9 à 2^24=16777216, soit même pas ma fortune en € :)
--
F.J.
Olivier Miakinen
2024-11-09 12:01:25 UTC
Permalink
Post by efji
[les entiers comme un sous-ensemble des nombres IEEE 754 double précision]
En effet, ça peut se concevoir, même si c'est perturbant pour un vieux
comme moi. J'aurais du mal à prendre des indices de tableaux comme des
nombres réels, mais on doit pouvoir s'habituer.
Je reviens à JavaScript. Les indices de tableaux n'y sont *pas* des nombres
réels ! Même si les nombres entiers sont codés selon la norme IEEE 754 qui
peut *aussi* coder des nombres non entiers, seuls les entiers sont utilisés
comme indices de tableaux. Je crois même (mais c'est à vérifier) que seuls
les entiers positifs entre 0 et 2^32−1 sont autorisés comme index. Donc pas
3,14, ni −2, ni 2^42.
Post by efji
Le truc embêtant c'est
qu'on perd toute la partie "exposant" du codage : en 64 bits la limite
est 2^53 = 9x10^15 au lieu de 2^63 = 9.2x10^18, on peut s'en contenter,
quoiqu'en adressage il ne soit pas impossible qu'on arrive rapidement à
cette valeur: 9x10^15 c'est 9000 terabits, soient 1000 TB. On y est presque.
Là tu trolles. Personne n'envisage d'indexer les bits ni même les bytes
d'un énorme disque dur en JavaScript. Tu disais toi-même à Thierry Loiseau
qu'il serait inenvisageable de chercher les nombres à l'origine de cette
enfilade au delà de 10^13 avec un langage interprété.
Post by efji
En 32 bits c'est impossible de faire ça car pour le plus grand entier on
passerait de 2^31=2x10^9 à 2^24=16777216, soit même pas ma fortune en € :)
Soit dit en passant, avec JavaScript il a toujours été possible de définir
des structures gérant des nombres entiers de taille indéterminée, et depuis
quelques années le type BigInt a même été inclus en standard.

***

Mais je reviens à ta phrase du début « j'aurais du mal à prendre des indices
de tableaux comme des nombres réels » et à une phrase d'un de tes articles
précédents « il n'y a pas d'entiers en javascript ».

Nous sommes dans le groupe consacré aux mathématiques, fr.sci.maths. Est-ce
que tu considères qu'il n'y a pas d'entiers dans le corps des rationnels ou
dans le corps des réels ?

Eh bien dans un langage tel que JavaScript, c'est pareil : l'ensemble des
nombres représentables est un sous-ensemble des rationnels¹ qui est lui-même
un sous-ensemble des réels, et ce sous-ensemble comporte entre autres tous
les nombres *entiers* compris entre −2^53 et +2^53.


¹ Plus certaines valeurs particulières telles que +∞, −∞ ou NaN.
--
Olivier Miakinen
efji
2024-11-09 12:34:45 UTC
Permalink
Post by Olivier Miakinen
Post by efji
[les entiers comme un sous-ensemble des nombres IEEE 754 double précision]
En effet, ça peut se concevoir, même si c'est perturbant pour un vieux
comme moi. J'aurais du mal à prendre des indices de tableaux comme des
nombres réels, mais on doit pouvoir s'habituer.
Je reviens à JavaScript. Les indices de tableaux n'y sont *pas* des nombres
réels ! Même si les nombres entiers sont codés selon la norme IEEE 754 qui
peut *aussi* coder des nombres non entiers, seuls les entiers sont utilisés
comme indices de tableaux. Je crois même (mais c'est à vérifier) que seuls
les entiers positifs entre 0 et 2^32−1 sont autorisés comme index. Donc pas
3,14, ni −2, ni 2^42.
J'espère pour javascript que tu te trompes :)
Se limiter au 32 bits, donc 2GB de mémoire, en 2025 c'est carrément
pathétique.
Post by Olivier Miakinen
Post by efji
Le truc embêtant c'est
qu'on perd toute la partie "exposant" du codage : en 64 bits la limite
est 2^53 = 9x10^15 au lieu de 2^63 = 9.2x10^18, on peut s'en contenter,
quoiqu'en adressage il ne soit pas impossible qu'on arrive rapidement à
cette valeur: 9x10^15 c'est 9000 terabits, soient 1000 TB. On y est presque.
Là tu trolles. Personne n'envisage d'indexer les bits ni même les bytes
d'un énorme disque dur en JavaScript. Tu disais toi-même à Thierry Loiseau
qu'il serait inenvisageable de chercher les nombres à l'origine de cette
enfilade au delà de 10^13 avec un langage interprété.
Il ne s'agit pas d'indexer un disque dur mais de la mémoire lorsqu'on
programme. Je pensais que depuis l'expérience malheureuse de MS-Dos ("je
me demande bien qui un jour pourrait avoir besoin de plus de 640Ko de
mémoire") tout le monde avait compris que les mémoires utilisées étaient
en progression exponentielle sans horizon de stabilisation :)

Moi aussi j'avais un DD de 20Mo dans ma jeunesse, pour taper ma thèse,
et je n'imaginais pas avoir quelques années plus tard, sur mon bureau,
une machine ayant 20000 fois plus de mémoire vive que ce DD (400GB) et
coûtant grosso modo le même prix compte-tenu de l'inflation.
Post by Olivier Miakinen
Post by efji
En 32 bits c'est impossible de faire ça car pour le plus grand entier on
passerait de 2^31=2x10^9 à 2^24=16777216, soit même pas ma fortune en € :)
Soit dit en passant, avec JavaScript il a toujours été possible de définir
des structures gérant des nombres entiers de taille indéterminée, et depuis
quelques années le type BigInt a même été inclus en standard.
***
Mais je reviens à ta phrase du début « j'aurais du mal à prendre des indices
de tableaux comme des nombres réels » et à une phrase d'un de tes articles
précédents « il n'y a pas d'entiers en javascript ».
Nous sommes dans le groupe consacré aux mathématiques, fr.sci.maths. Est-ce
que tu considères qu'il n'y a pas d'entiers dans le corps des rationnels ou
dans le corps des réels ?
Ce n'est pas ce que je dis, j'ai juste dit que ça choque mes habitudes
de vieux, mais pourquoi pas si on y gagne quelque chose. Mais en fait je
ne vois pas ce qu'on y gagne :)
--
F.J.
Samuel Devulder
2024-11-09 15:53:59 UTC
Permalink
Post by efji
Ce n'est pas ce que je dis, j'ai juste dit que ça choque mes habitudes
de vieux, mais pourquoi pas si on y gagne quelque chose. Mais en fait je
ne vois pas ce qu'on y gagne 🙂
Une absence de typage rend les langages bien plus simples à l'usage. Il
s'agit de langages de script pas de programmation. On écrit pas une
application avec ca mais des maquettes pour tester rapidement un truc.

Lua va assez loin dans la réduction du nombre de types de données puis
que tableaux et dictionnaires sont confondus, et à l'usage c'est très
agréable je dois bien avouer.

sam.
Michel Talon
2024-11-09 18:39:17 UTC
Permalink
Post by Samuel Devulder
Post by efji
Ce n'est pas ce que je dis, j'ai juste dit que ça choque mes habitudes
de vieux, mais pourquoi pas si on y gagne quelque chose. Mais en fait
je ne vois pas ce qu'on y gagne 🙂
Une absence de typage rend les langages bien plus simples à l'usage. Il
s'agit de langages de script pas de programmation. On écrit pas une
application avec ca mais des maquettes pour tester rapidement un truc.
Lua va assez loin dans la réduction du nombre de types de données puis
que tableaux et dictionnaires sont confondus, et à l'usage c'est très
agréable je dois bien avouer.
sam.
Et bien, pour passer de langages récents à un langage très ancien voici
une solution avec Common Lisp (en fait sbcl) qui lui aussi a
l'avantage d'un programme non typé (sauf si on déclare le type des
variables) avec gestion automatique de la mémoire, possibilité de
programmer pas à pas à la console, comme python ou lua, mais en outre
est compilé automatiquement (avec sbcl)
ce qui donne une vitesse d'exécution raisonnable, contrairement à python
par exemple.
Voici le programme:

(defun print-bizarre-squares (N str)
(let ((k 1) (l 10))
(dotimes (i N 'done)
(let ((j (* i i)))
(when (<= l j)
(incf k)
(setq l (* 10 l)))
;; Here 10^(k-1) <= j < 10^k, j has k digits
(if (evenp k) (test-if-bizarre i j (expt 10 (/ k 2)) str))))))

(defun test-if-bizarre (i j l str)
(multiple-value-bind (a b) (floor (/ j l))
(if (= i (+ a (* l b))) (format str " ~7d ~d ~%" i j))))

(defparameter N (expt 10 7)) ; 10^7
(with-open-file (str "list-of-bizarre" :direction :output :if-exists
:supersede)
(time (print-bizarre-squares N str)))

Le résultat est écrit dans "list-of-bizarre" et le temps d'éxécution
est imprimé.
Sur ma machine (2993.03 BogoMIPS ) assez lente, j'obtiens:

Evaluation took:
7.894 seconds of real time
7.891697 seconds of total run time (7.887671 user, 0.004026 system)
[ Run times consist of 0.055 seconds GC time, and 7.837 seconds
non-GC time. ]
99.97% CPU
11,815,133,039 processor cycles
486,145,312 bytes consed

Finalement le résultat obtenu est:
9 81
45 2025
55 3025
99 9801
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
533170 284270248900
538461 289940248521
609687 371718237969
643357 413908229449
648648 420744227904
670033 448944221089
681318 464194217124
791505 626480165025
812890 660790152100
818181 669420148761
851851 725650126201
857143 734694122449
961038 923594037444
994708 989444005264
999999 999998000001
4444444 19753082469136
4927941 24284602499481
5072059 25725782499481
5555556 30864202469136
9372385 87841600588225
9999999 99999980000001
--
Michel Talon
Samuel Devulder
2024-11-10 02:40:46 UTC
Permalink
Post by Michel Talon
(defun print-bizarre-squares (N str)
  (let ((k 1) (l 10))
    (dotimes (i N 'done)
      (let ((j (* i i)))
         (when (<= l j)
           (incf k)
           (setq l (* 10 l)))
        ;; Here 10^(k-1) <= j < 10^k, j has k digits
        (if (evenp k) (test-if-bizarre i j  (expt 10 (/ k 2)) str))))))
(defun test-if-bizarre (i j l str)
  (multiple-value-bind (a b) (floor (/ j l))
    (if (= i (+ a (* l b))) (format str  " ~7d      ~d ~%" i j))))
(defparameter N (expt 10 7)) ; 10^7
(with-open-file (str "list-of-bizarre" :direction :output :if-
exists :supersede)
  (time (print-bizarre-squares N str)))
Quelque part c'est moyennement lisible(*) par rapport à cet version plus
"naturelle" du point de vue algorithmique :

----8<-------------------------------------
i = 0
n = 1
p = 1
q = 10
repeat
n = n + 1
if n>=q then
p = q
q = q*10
end
m = n*n
a = math.floor(m / q)
b = math.floor(m % q)
if a+b==n and a>=p then
i = i + 1
print(i, n, m)
end
until n > 1E7
----8<-------------------------------------

Qui est directement interprétable par Lua et qui donne la même liste de
45 nombres en même pas deux secondes dans un browser web.

A noter que la condition "a>=p" évite de tomber sur des nombres où l'on
a besoin du zero implicite devant m=n² pour avoir un découpage plus
naturel. Si on retire cette condition, on tombe sur ces 10 solutions
supplémentaires non trouvé par le programme Lisp amenant à un total de
55 carrés bizarres <= 1E7.

1 297 88209 (297 = 088 + 209)
2 2223 4941729 (2223 = 0494 + 1729)
3 2728 7441984 etc.
4 17344 300814336
5 22222 493817284
6 142857 20408122449
7 148149 21948126201
8 181819 33058148761
9 187110 35010152100
10 208495 43470165025

Pour expérimenter par soi-même: https://onecompiler.com/lua/42xp2gahe

sam.

____
(*) lisp = Lost In Stupid Parentheses
= Lots of Irritating Superfluous Parentheses
Michel Talon
2024-11-10 11:25:39 UTC
Permalink
Post by Samuel Devulder
----8<-------------------------------------
i = 0
n = 1
p = 1
q = 10
repeat
  n = n + 1
  if n>=q then
    p = q
    q = q*10
  end
  m = n*n
  a = math.floor(m / q)
  b = math.floor(m % q)
  if a+b==n and a>=p then
    i = i + 1
    print(i, n, m)
  end
until n > 1E7
----8<-------------------------------------
Très intéressant. La version lisp du même programme , avec les mêmes
variables,
(il s'exécute dans le même temps que ma version), est:

(let ((i 0)(p 1)(q 10) m )
(do ((n 2 (incf n))) ((> n (expt 10 7)) 'DONE)
(if (>= n q)
(progn (setq p q)
(setq q (* 10 q))))
(setq m (* n n))
(multiple-value-bind (a b) (floor (/ m q))
(if (and (= n (+ a (* q b))) (>= a p))
(progn (incf i)
(format t "~d ~d ~d ~%" i n m))))))

La seule différence est que, à ma connaissance, on ne dispose pas
de m%q si bien qu'on doit utiliser (floor (/ m q)) qui produit le
quotient plus le reste, donc on doit utiliser multiple-value-bind
pour récupérer les deux valeurs et remultiplier le reste par q
pour obtenir m%q. Or en lisp il y a des tas de types de données,
integer, rational, float, etc et floor s'adapte à tous ces types.
La documentation dit que:

"
All of these functions perform type conversion operations on
numbers.

The remainder is an integer if both x and y are integers, is a
rational if both x and y are rationals, and is a float if either
x or y is a float.
"

Autrement dit floor est une fonction très compliquée qui prend
beaucoup de temps à l'exécution. De fait utilisant le profiler de
lisp on voit que presque tout le temps d'exécution est à cet
endroit. Clairement lua est beaucoup plus efficace ici, et doit
utiliser des fonctions spécifiques pour les entiers. De plus ta
version de lua doit utiliser lua-jit pour tourner aussi vite.

J'ai essayé de spécifier le type des variables et de demander une
optimisation maximale au compilateur, ça ne change rien. En fait
ça ne marche pas très bien avec les entiers, par contre ça marche
aisément avec des floats, et on obtient facilement des
performances proches de celles du C.

En ce qui concerne la lisibilité, je suis bien d'accord avec toi,
la syntaxe type python ou, ce qui est à peu prés pareil lua, est
ce qu'il y a de mieux. Néanmoins, si tu compares les programmes
lisp et lua tu vois que c'est extrêmement similaire, aux
parenthèses prés. Avec un peu d'habitude, on ne voit presque plus
ces parenthèses. L'autre grande différence est la notation
préfixe, ou l'opération apparaît en premier après la parenthèse
ouvrante, (/ m q) au lieu de m/q
(>= a p) au lieu de a >= p, etc.

Ca rend l'interprétation du code extrêmement simple pour lisp.
Devant une "forme" (A B C) on doit d'abord évaluer B et C puis
appliquer l'opérateur A à ces résultats, et ceci récursivement,
bien sûr.
(> n (expt 10 7))
on évalue n, on évalue (expt 10 7), 10 -> 10
7 -> 7 on applique expt -> 10^7 et enfin on évalue >, est-ce que
n > 10^7 ? Avec les parenthèses on a une uniformité parfaite,
aucun cas particulier, aucune ambiguité. Si on fait un
copier-coller, aucun problème de Tab et Space etc.

Finalement comme tu sais la grande spécificité de lisp est
l'existence des macros, qui fait qu'il n'y a pas rééllement de
syntaxe, à part les choses les plus basiques, puisqu'on peut
créer sa propre syntaxe à volonté. Par exemple ton repeat
...until est ici la boucle do
(do ((n 2 (incf n))) ((> n (expt 10 7)) 'DONE) .... Ceci est en
fait une macro: dans laquelle ((n 2 (incf n))) est une liste de
variables à initialiser et incrémenter, on pourrait avoir ((n
1 (incf n))(m 2 (incf m))), la parenthèse extérieure sert à
grouper ces déclarations et aussi au mécanisme de macro de
repérer son premier argument, d'ailleurs heureusement que
l'expansion de macros se fait sans évaluation, sinon
(n 1 (incf n))
poserait problème , n n'étant pas une fonction. Le deuxième
argument de la macro do est la condition de terminaison
((> n (expt 10 7)) 'DONE)
qui est en fait un liste de cette condition
et de la valeur à retourner, ici, une fantaisie, le symbole
'DONE, où le ' empêche l'évaluation. En bref ceci pour expliquer
l'utilité fondamentale des parenthèses.

Finalement la déclaration des variables par let etc. n'est pas
forcément une mauvaise chose, ça permet de s'assurer que ce ne
sont pas des variables globales comme le N de (defparameter N)
donc le compilateur les traite avec plus d'efficacité, elles ont
une visibilité purement lexicale et sont allouées sur la pile, le
compilateur sait exactement ce qui les modifie, et optimise en
conséquence. On a la même idée dans le langage rust.
--
Michel Talon
efji
2024-11-10 14:17:09 UTC
Permalink
Post by Michel Talon
ouvrante, (/ m q) au lieu de m/q
(>= a p) au lieu de a >= p, etc.
Quand je disais qu'il y avait des informaticiens pervers. Franchement,
dans quel esprit tordu un truc pareil peut-il germer?
C'est comme l'histoire de la division (rien que ça!) qui change quand on
passe de python 2 à python 3. Complètement surréaliste.
--
F.J.
Michel Talon
2024-11-10 17:42:42 UTC
Permalink
Post by efji
Quand je disais qu'il y avait des informaticiens pervers. Franchement,
dans quel esprit tordu un truc pareil peut-il germer?
Comme je l'ai expliqué, la notation préfixe est sans ambiguité, on peut
écrire
(+ 1 2 3 4) et on va trouver 10, en notation usuelle il faut que le
compilateur rame
pour comprendre 1+2+3+4, d'où les machines à état des grammaires LR(1)
etc. pour
compiler le C, Ce qui fait que le lisp peut être compilé à la volée en
interactif en un temps imperceptible. La notation postfix des
calculatrices HP ou de postscript
a les mêmes avantages, sauf qu'il faut que chaque fonction ait un nombre
fixe d'arguments, que la machine va chercher sur la pile. Après, lisp a
les macros, qui permettent de redéfinir la syntaxe, et il existe en
effet des systèmes qui comprennent la notation infix usuelle des
opérations. Par exemple le système de Mark Kantrowitz
https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/infix.cl
Ca utilise le fait qu'on peut tout modifier, y compris le programme
"reader" qui lit
le code en premier.
Quand on a chargé infix.cl on peut faire:
;;; Syntax:
;;;
;;; Begin the reader macro with #I( and end it with ). For example,
;;; #I( x^^2 + y^^2 )
;;; is equivalent to the Lisp form
;;; (+ (expt x 2) (expt y 2))
;;; but much easier to read according to some folks.
;;;
;;; If you want to see the expansion, type a quote before the #I form
;;; at the Lisp prompt:
;;; > '#I(if x<y<=z then f(x)=x^^2+y^^2 else f(x)=x^^2-y^^2)
;;; (IF (AND (< X Y) (<= Y Z))
;;; (SETF (F X) (+ (EXPT X 2) (EXPT Y 2)))
;;; (SETF (F X) (- (EXPT X 2) (EXPT Y 2))))
Voilà, je crois que maxima, qui utilise la notation usuelle, a un
mécanisme de ce genre.
--
Michel Talon
Michel Talon
2024-11-10 15:07:09 UTC
Permalink
Post by Michel Talon
Autrement dit floor est une fonction très compliquée qui prend
beaucoup de temps à l'exécution. De fait utilisant le profiler de
lisp on voit que presque tout le temps d'exécution est à cet
endroit.
En fait j'avais mal compris la documentation lisp de floor, et oublié
qu'il y a une fonction mod, si bien que j'ai réécrit le programme avec
ces fonctions et des déclarations appropriées, et j'ai enfin un temps
d'exécution correct, tout en étant plus proche de ton programme:

(time
(let ((i 0)(p 1)(q 10)(m 1)(a 1)(b 1))
(declare (fixnum i p q m a b)
(optimize (speed 3)(safety 0)))
(do ((n 2 (incf n)))
((> n (expt 10 7)) 'DONE)
(if (>= n q)
(progn (setq p q)
(setq q (* 10 q))))
(setq m (* n n))
(setq a (floor m q))
(setq b (mod m q))
(if (and (= n (+ a b))
(>= a p))
(progn (incf i)
(format t "~d ~d ~d ~%" i n m)))))))

Ce qui donne:

1 9 81
2 45 2025
3 55 3025
4 99 9801
...
44 9372385 87841600588225
45 9999999 99999980000001
Evaluation took:
0.643 seconds of real time
0.641880 seconds of total run time (0.641880 user, 0.000000 system)
99.84% CPU
961,544,359 processor cycles
32,736 bytes consed

En particulier il y a infiniment moins de mémoire allouée au calcul
(bytes consed ...).

Du coup je suis monté jusqu'à 10^9 le calcul prend 67s. les derniers
résultats sont:
65 94520547 8934133805179209
66 99999999 9999999800000001
67 332999667 110888778222110889
68 432432432 186997808245434624
69 567567568 322132944245434624
70 667000333 444889444222110889
71 765432099 585886298179545801
72 999999999 999999998000000001

Au delà on dépasse la taille d'un fixnum
most-positive-fixnum -> 4611686018427387903
donc il faut remplacer la déclaration fixnum par integer ce qui permet à
lisp de passer aux bigint en cas de besoin, mais avec la perte de
performance correspondante.

Ceci illustre qu'on peut typer les variables, le système détecte alors
les erreurs de type, et dans ce cas le compilateur peut produire du code
proche de C, sinon le système se débrouille pour produire des
rationnels, par exemple on peut avoir 3/5
et calculer (+ 3/10 21/15) -> 17/10 , ce qui suppose des calculs de
pgcd, ou bien le résultat peut contenir des nombres gigantesques (big
integers) tout ça de façon automatique, mais ça a un prix. Bref il y a
le meilleur des deux mondes, à la fois pas de typage du tout, et si on
le veut un typage fort.
--
Michel Talon
efji
2024-11-10 15:34:43 UTC
Permalink
Post by Michel Talon
Post by Michel Talon
Autrement dit floor est une fonction très compliquée qui prend
beaucoup de temps à l'exécution. De fait utilisant le profiler de
lisp on voit que presque tout le temps d'exécution est à cet
endroit.
En fait j'avais mal compris la documentation lisp de floor, et oublié
qu'il y a une fonction mod, si bien que j'ai réécrit le programme avec
ces fonctions et des déclarations appropriées, et j'ai enfin un temps
(time
 (let ((i 0)(p 1)(q 10)(m 1)(a 1)(b 1))
   (declare (fixnum i p q m a b)
        (optimize (speed 3)(safety 0)))
   (do ((n 2 (incf n)))
       ((> n (expt 10 7)) 'DONE)
     (if (>= n q)
     (progn (setq p q)
        (setq q (* 10 q))))
     (setq m (* n n))
     (setq a (floor m q))
     (setq b (mod m q))
     (if (and (= n (+ a b))
          (>= a p))
     (progn (incf i)
        (format t "~d ~d ~d ~%" i n m)))))))
1 9 81
2 45 2025
3 55 3025
4 99 9801
...
44 9372385 87841600588225
45 9999999 99999980000001
  0.643 seconds of real time
  0.641880 seconds of total run time (0.641880 user, 0.000000 system)
  99.84% CPU
  961,544,359 processor cycles
  32,736 bytes consed
En particulier il y a infiniment moins de mémoire allouée au calcul
(bytes consed ...).
Du coup je suis monté jusqu'à  10^9  le calcul prend 67s.  les derniers
OK c'est génial le lisp (franchement rarement vu langage aussi peu
lisible) :)
Même chose en fortran ou C :
en utilisant des entiers 64 bits, suffisants pour aller jusqu'à 10^9: 0.67s
avec des entiers 128 bits permettant de monter au ciel : 8.43s

Il doit y avoir moyen de gagner en minimisant toutes les opérations sur
des 128 bits qui semblent outrageusement coûteuses.
--
F.J.
efji
2024-11-10 09:43:05 UTC
Permalink
Post by Michel Talon
Et bien, pour passer de langages récents à un langage très ancien voici
une solution avec Common Lisp  (en fait sbcl)  qui lui aussi a
l'avantage d'un programme non typé (sauf si on déclare le type des
variables) avec gestion automatique de la mémoire, possibilité de
programmer pas à pas à la console, comme python ou lua, mais en outre
est compilé automatiquement (avec sbcl)
ce qui donne une vitesse d'exécution raisonnable, contrairement à python
par exemple.
(defun print-bizarre-squares (N str)
  (let ((k 1) (l 10))
    (dotimes (i N 'done)
      (let ((j (* i i)))
         (when (<= l j)
           (incf k)
           (setq l (* 10 l)))
        ;; Here 10^(k-1) <= j < 10^k, j has k digits
        (if (evenp k) (test-if-bizarre i j  (expt 10 (/ k 2)) str))))))
(defun test-if-bizarre (i j l str)
  (multiple-value-bind (a b) (floor (/ j l))
    (if (= i (+ a (* l b))) (format str  " ~7d      ~d ~%" i j))))
(defparameter N (expt 10 7)) ; 10^7
(with-open-file (str "list-of-bizarre" :direction :output :if-
exists :supersede)
  (time (print-bizarre-squares N str)))
Le résultat est écrit dans "list-of-bizarre"  et le temps d'éxécution
est imprimé.
  7.894 seconds of real time
  7.891697 seconds of total run time (7.887671 user, 0.004026 system)
  [ Run times consist of 0.055 seconds GC time, and 7.837 seconds non-
GC time. ]
  99.97% CPU
  11,815,133,039 processor cycles
  486,145,312 bytes consed
       9      81
      45      2025
      55      3025
      99      9801
     703      494209
     999      998001
    4950      24502500
    5050      25502500
    7272      52881984
    7777      60481729
    9999      99980001
   77778      6049417284
   82656      6832014336
   95121      9048004641
   99999      9999800001
  318682      101558217124
  329967      108878221089
  351352      123448227904
  356643      127194229449
  390313      152344237969
  461539      213018248521
  466830      217930248900
  499500      249500250000
  500500      250500250000
  533170      284270248900
  538461      289940248521
  609687      371718237969
  643357      413908229449
  648648      420744227904
  670033      448944221089
  681318      464194217124
  791505      626480165025
  812890      660790152100
  818181      669420148761
  851851      725650126201
  857143      734694122449
  961038      923594037444
  994708      989444005264
  999999      999998000001
 4444444      19753082469136
 4927941      24284602499481
 5072059      25725782499481
 5555556      30864202469136
 9372385      87841600588225
 9999999      99999980000001
Michel Talon me met la honte :)
Incrédule je relis le résultat : "7.891697 seconds of total run time",
alors qu'il va à un ordre de grandeur plus loin que moi !
Et mon programme prenait presque 7 minutes sur mon Mac M2Max de course...

J'essaye de comprendre le programme lisp qui est une langue étrangère,
je m'aide de ChatGPT, et je comprends la buse que je suis :)
Je testais tous les couples (n,p) où n et p sont < 10^7, alors qu'il
suffit de tester tous les n<10^7 et de le mettre au carré... Bref,
j'avais écrit bêtement un algo de complexité O(n^2) alors que celui de
Talon est en O(n).

Une fois réécrit correctement, l'algo me prend 0.05s pour aller à 10^7.
Du coup ça rend plus gourmand (le classique effet rebond : quand on
optimise un machin, on a envie d'en consommer plus, vrai dans
l'algorithmique comme dans la transition énergétique). Voici la suite de
la liste (11 heures de calcul) dans laquelle on note plusieurs choses :

* il y en a bien plus entre 10^{2k+1} et 10^{2k+2} qu'entre 10^{2k} et
10^{2k+1}.

* Dans chaque séquence il n'y a rien en dessous 3.16 x 10^{n} car on les
a éliminés artificiellement en imposant que le carré ait exactement
(2n+2) chiffres, sans "0 muet" devant. Ce n'est peut-être pas nécessaire.

* En plus de ceux déjà repéré : 999 = 10^3-1, 500500, 499500 =
5*10^{2k+1} ± 5*10^k,
on en trouve plein de rigolos :
4444444, 36363636, 38883889, 61116111, 63636364, 74747475, 88888888,
432432432, 567567568, 3888938889, 4132841328, 4756047561, 6111061111,
7979797980, 8888888889, 9090909091, 9132791328, 9756097560, 44444444445,
55555555555, 324324324324, 425925425926, 590909590909, 593554593555,
604247604247, 675675675676, 695156695156, 730769730769, 733414733415,
740774077407, 749749749750, 750249750250, 804843804843, 831683168316,
909090909090, 925925925925, 980518980519 avec presque l'impression que
la densité de rigolos augmente quand on monte :)


9 81
45 2025
55 3025
99 9801
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
533170 284270248900
538461 289940248521
609687 371718237969
643357 413908229449
648648 420744227904
670033 448944221089
681318 464194217124
791505 626480165025
812890 660790152100
818181 669420148761
851851 725650126201
857143 734694122449
961038 923594037444
994708 989444005264
999999 999998000001
4444444 19753082469136
4927941 24284602499481
5072059 25725782499481
5555556 30864202469136
9372385 87841600588225
9999999 99999980000001
36363636 1322314023140496
38883889 1511956823764321
44363341 1968106024682281
44525548 1982524424700304
49995000 2499500025000000
50005000 2500500025000000
55474452 3077414824700304
55636659 3095437824682281
61116111 3735179023764321
63636364 4049586823140496
69115816 4776996021345856
74747475 5587185018875625
75247525 5662190018625625
80226927 6436359815863329
80726977 6516844815558529
83409436 6957134013838096
86358636 7457814011780496
88888888 7901234409876544
91838088 8434234407495744
94520547 8934133805179209
99999999 9999999800000001
332999667 110888778222110889
432432432 186997808245434624
567567568 322132944245434624
667000333 444889444222110889
765432099 585886298179545801
999999999 999999998000000001
3846956652 14799075482367049104
3888938889 15123845682376554321
4090859091 16735128102417346281
4132841328 17080377442424803584
4756047561 22619988402494048721
4798029798 23021089942495920804
4958067763 24582435942499824169
4999950000 24999500002500000000
5000050000 25000500002500000000
5041932237 25421080682499824169
5201970202 27060493982495920804
5243952439 27499037182494048721
5867158672 34423550882424803584
5909140909 34917946282417346281
6111061111 37345067902376554321
6153043348 37859942442367049104
7979797980 63677175801612080400
8223700419 67629248581460775561
8888888889 79012345680987654321
9090909091 82644628100826446281
9132791328 83407877440792003584
9334811530 87138706300620940900
9756097560 95181439600237953600
9999999999 99999999980000000001
44444444445 1975308642024691358025
55555555555 3086419753024691358025
75861343351 5754943415018311909201
79694212204 6351167458816182537616
99999999999 9999999999800000000001
321678321679 103476942638218201379041
324324324324 105186267348219138056976
329037665671 108265785430220771880241
331683668317 110014055828221669612489
333299996667 111088887778222211108889
335016335017 112235944728222780390289
340659340659 116048786378224610554281
346638010005 120157909980226480100025
363473026840 132112641240231360385600
395752395753 156619958744239132437009
399086062453 159269685244239816377209
403111739745 162499074720240612665025
405757742391 164639345510241118396881
406445406445 165197868420241247538025
409090409091 167354962810241735446281
422592759226 178584640150244008119076
425925425926 181412468450244512957476
428571428572 183673469388244897959184
435930772564 190035638468245895134096
437547100914 191447465518246099635396
473160136527 223880514798249279621729
480519480519 230898971158249620509361
489995153362 240095250318249899903044
496666833300 246677943300249988890000
497354497354 247361496038249993001316
499999500000 249999500000250000000000
500000500000 250000500000250000000000
502645502646 252652501330249993001316
503333166700 253344276700249988890000
510004846638 260104943594249899903044
519480519481 269860010120249620509361
526839863473 277560241744249279621729
562452899086 316353263690246099635396
564069227436 318174093340245895134096
571428571428 326530612244244897959184
574074574074 329561616598244512957476
577407240774 333399121698244008119076
590909590909 349174144628241735446281
593554593555 352307055530241247538025
594242257609 353123860728241118396881
596888260255 356275595230240612665025
600913937547 361097560338239816377209
604247604247 365115167238239132437009
636526973160 405166587560231360385600
653361989995 426881889970226480100025
659340659341 434730105060224610554281
664983664983 442203274694222780390289
666700003333 444488894444222211108889
668316331683 446646719194221669612489
670962334329 450190454088220771880241
675675675676 456537618700219138056976
678321678321 460120299280218201379041
687797351164 473065196268214732154896
695156695156 483242830820211913864336
727436064069 529163227308198272836761
730769730769 534024399408196745331361
733414733415 537897171190195517562225
740774077407 548746233758192027843649
749749749750 562124687250187625062500
750249750250 562874687750187375062500
757609094242 573971539678183637554564
760255096888 577987812344182267284544
761871425238 580448068594181423356644
766584766585 587652204360178932562225
769230769230 591715976330177514792900
804843804843 647773550194157070254649
821678821678 675156085994146522735684
824323824324 679509767348144814056976
827657491024 685016922448142640568576
831683168316 691696892460139986275856
834329170962 696105165518138224005444
835016835016 697253114760137763720256
840658840659 706707286378133951554281
843992507359 712323352478131669154881
851164187797 724480474588126683713209
895752895752 802373250248093379645504
901731565098 813119815494088611749604
906444906445 821642368420084802538025
909090909090 826446280990082644628100
918066581433 842846247944075220333489
918566581933 843764565444074802016489
925238261871 856065841230069172420641
925925925925 857338820300068587105625
928571928571 862245826530066326102041
934901598268 874040998444060860599824
980518980519 961417471158019101509361
991024327657 982129218008008895109649
992640656007 985335471958007305184049
997353997354 994714996038002639001316
999999999999 999999999998000000000001
--
F.J.
Olivier Miakinen
2024-11-10 10:15:00 UTC
Permalink
Post by efji
* En plus de ceux déjà repéré : 999 = 10^3-1, 500500, 499500 =
5*10^{2k+1} ± 5*10^k,
4444444, 36363636, 38883889, 61116111, 63636364, 74747475, 88888888,
432432432, 567567568, 3888938889, 4132841328, 4756047561, 6111061111,
7979797980, 8888888889, 9090909091, 9132791328, 9756097560, 44444444445,
55555555555, 324324324324, 425925425926, 590909590909, 593554593555,
604247604247, 675675675676, 695156695156, 730769730769, 733414733415,
740774077407, 749749749750, 750249750250, 804843804843, 831683168316,
909090909090, 925925925925, 980518980519 avec presque l'impression que
la densité de rigolos augmente quand on monte :)
Je me suis amusé à regarder aussi les puissances troisième et quatrième en
plus des carrés, et (surtout si on s'autorise de compter les zéros initiaux)
on trouve des nombres rigolos qui fonctionnent dans les trois cas :

3888938889
= √ 15123845682376554321
= 1512384568+2376554321
= ∛ 058815711625428924040757889369
= 0588157116+2542892404+0757889369
= ∜ 0228730708224339944007530377000663771041
= 0228730708+2243399440+0753037700+063771041

4999950000
= √ 24999500002500000000
= 2499950000+2500000000
= ∛ 124996250037499875000000000000
= 1249962500+3749987500+0000000000
= ∜ 0624975000374997500006250000000000000000
= 0624975000+3749975000+0625000000+0000000000

5000050000
= √ 25000500002500000000
= 2500050000+2500000000
= ∛ 125003750037500125000000000000
= 1250037500+3750012500+0000000000
= ∜ 0625025000375002500006250000000000000000
= 0625025000+3750025000+0625000000+0000000000


D'autres exemples de nombres rigolos, en s'interdisant les zéros initiaux avant
découpage :

671671
∜ 203529043026143035282081 = 203529+043026+143035+282081

63636364
√ 4049586823140496 = 40495868+23140496
∛ 257700981126972226596544 = 25770098+11269722+26596544

5867158672
√ 34423550882424803584
= 3442355088+2424803584
∜ 1184980855354889473501540380260979245056
= 1184980855+3548894735+0154038026+0979245056

6666666667
∜ 1975308642370370370400000000000987654321
= 1975308642+3703703704+0000000000+0987654321
--
Olivier Miakinen
Thierry Loiseau
2024-11-10 11:59:57 UTC
Permalink
Post by Michel Talon
9 81
45 2025
55 3025
99 9801
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
Et on n'y trouve pas 494209 ?
--
* * __*__ *
* * * -----oOOo--- O ---oOOo------- * *
http://astrophoto.free.fr *
* * -------- oOOo oOOo ---------- *
efji
2024-11-10 14:19:04 UTC
Permalink
Post by Thierry Loiseau
Post by Michel Talon
9 81
45 2025
55 3025
99 9801
703 494209
999 998001
4950 24502500
5050 25502500
7272 52881984
7777 60481729
9999 99980001
77778 6049417284
82656 6832014336
95121 9048004641
99999 9999800001
318682 101558217124
329967 108878221089
351352 123448227904
356643 127194229449
390313 152344237969
461539 213018248521
466830 217930248900
499500 249500250000
500500 250500250000
Et on n'y trouve pas 494209 ?
Pourquoi, on devrait ?
494209^2 = 244242535681
244242+535681 = 779923
--
F.J.
Michel Talon
2024-11-11 22:13:58 UTC
Permalink
Post by Michel Talon
Et bien, pour passer de langages récents à un langage très ancien voici
une solution avec Common Lisp  (en fait sbcl)  qui lui aussi a
l'avantage d'un programme non typé (sauf si on déclare le type des
variables) avec gestion automatique de la mémoire, possibilité de
programmer pas à pas à la console, comme python ou lua, mais en outre
est compilé automatiquement (avec sbcl)
ce qui donne une vitesse d'exécution raisonnable, contrairement à python
par exemple.
Voici le programme: .....
Suite aux discussions voici une version améliorée du même algorithme,
qui est plus efficace que celui de Samuel, je crois:

(defun print-bizarre-squares (N str)
(let ((k 1) (l 10) (m 1) (p 0))
(declare (word k l m p)
(optimize (speed 3) (safety 0)))
(dotimes (i N 'done)
(declare (word i))
(let ((j (* i i)))
(declare (word j))
(when (<= l j)
(incf k)
(setq l (* 10 l)) ; 10^k
(if (evenp k) (setq m (* 10 m)))) ; 10^(k/2) for k even
;; Here 10^(k-1) <= j < 10^k, j has k digits
(if (and (evenp k)
(= i (+ (floor j m) (mod j m)))) ; computed only for k even
(progn (incf p)
(format str "~4d ~10d ~d ~%" p i j)))))))


(defparameter N (expt 10 9)) ; 10^9
(with-open-file (str "list-of-bizarre" :direction :output :if-exists
:supersede)
(time (print-bizarre-squares N str)))


Sans aucune déclaration il tourne en 0.8s pour N=10^7 comparé aux 8s
précédemment indiquées, soit un facteur 10 grâce à l'amélioration de
l'usage de floor et mod. Avec les déclarations ci-dessus il tourne en
0.4s J'ai déclaré toutes les variables en type word, c'est à dire
(unsigned-int 64), ce qui est sbcl spécifique.
La version sans déclaration tourne quand même 1.7/0.8 soit 2 fois plus
vite que la version lua, ce qui est pas mal pour lua, je suppose que
python serait beaucoup plus lent (j'ai fait tourner
https://onecompiler.com/lua/42xp2gahe sur ma machine, en 1.7s).

Du coup j'ai fait tourner le programme avec N=10^9
Ce qui donne:
Evaluation took:
41.985 seconds of real time
41.969659 seconds of total run time (41.957832 user, 0.011827 system)
99.96% CPU
62,838,884,786 processor cycles
0 bytes consed
Noter qu'aucun espace mémoire n'a été alloué dynamiquement sur le tas!
Je pense qu'on est là vers des performances proches du C. Peut être ça
peut convaincre certains que les très vieux langages, comme Common Lisp
(ou Fortran) ont des atouts non négligeables....

Voici le résultat dans list-of-bizarre
1 9 81
2 45 2025
3 55 3025
4 99 9801
5 703 494209
6 999 998001
7 4950 24502500
8 5050 25502500
9 7272 52881984
10 7777 60481729
11 9999 99980001
12 77778 6049417284
13 82656 6832014336
14 95121 9048004641
15 99999 9999800001
16 318682 101558217124
17 329967 108878221089
18 351352 123448227904
19 356643 127194229449
20 390313 152344237969
21 461539 213018248521
22 466830 217930248900
23 499500 249500250000
24 500500 250500250000
25 533170 284270248900
26 538461 289940248521
27 609687 371718237969
28 643357 413908229449
29 648648 420744227904
30 670033 448944221089
31 681318 464194217124
32 791505 626480165025
33 812890 660790152100
34 818181 669420148761
35 851851 725650126201
36 857143 734694122449
37 961038 923594037444
38 994708 989444005264
39 999999 999998000001
40 4444444 19753082469136
41 4927941 24284602499481
42 5072059 25725782499481
43 5555556 30864202469136
44 9372385 87841600588225
45 9999999 99999980000001
46 36363636 1322314023140496
47 38883889 1511956823764321
48 44363341 1968106024682281
49 44525548 1982524424700304
50 49995000 2499500025000000
51 50005000 2500500025000000
52 55474452 3077414824700304
53 55636659 3095437824682281
54 61116111 3735179023764321
55 63636364 4049586823140496
56 69115816 4776996021345856
57 74747475 5587185018875625
58 75247525 5662190018625625
59 80226927 6436359815863329
60 80726977 6516844815558529
61 83409436 6957134013838096
62 86358636 7457814011780496
63 88888888 7901234409876544
64 91838088 8434234407495744
65 94520547 8934133805179209
66 99999999 9999999800000001
67 332999667 110888778222110889
68 432432432 186997808245434624
69 567567568 322132944245434624
70 667000333 444889444222110889
71 765432099 585886298179545801
72 999999999 999999998000000001
--
Michel Talon
efji
2024-11-11 22:31:08 UTC
Permalink
Post by Michel Talon
Post by Michel Talon
Et bien, pour passer de langages récents à un langage très ancien
voici une solution avec Common Lisp  (en fait sbcl)  qui lui aussi a
l'avantage d'un programme non typé (sauf si on déclare le type des
variables) avec gestion automatique de la mémoire, possibilité de
programmer pas à pas à la console, comme python ou lua, mais en outre
est compilé automatiquement (avec sbcl)
ce qui donne une vitesse d'exécution raisonnable, contrairement à
python par exemple.
Voici le programme: .....
Suite aux discussions voici une version améliorée du même algorithme,
(defun print-bizarre-squares (N str)
  (let ((k 1) (l 10) (m 1) (p 0))
    (declare (word k l m p)
         (optimize (speed 3) (safety 0)))
    (dotimes (i N 'done)
      (declare (word i))
      (let ((j (* i i)))
    (declare (word j))
    (when (<= l j)
      (incf k)
      (setq l (* 10 l))  ; 10^k
      (if (evenp k) (setq m (* 10 m)))) ; 10^(k/2) for k even
    ;; Here 10^(k-1) <= j < 10^k, j has k digits
    (if (and (evenp k)
         (= i (+ (floor j m) (mod j m))))  ; computed only for k even
        (progn  (incf p)
            (format str  "~4d ~10d ~d ~%" p i j)))))))
(defparameter N (expt 10 9)) ; 10^9
(with-open-file (str "list-of-bizarre" :direction :output :if-
exists :supersede)
  (time (print-bizarre-squares N str)))
Sans aucune déclaration   il tourne en 0.8s pour N=10^7  comparé aux 8s
précédemment indiquées, soit un facteur 10 grâce à l'amélioration de
l'usage de floor et mod. Avec les déclarations ci-dessus il tourne en
0.4s J'ai déclaré toutes les variables en type word, c'est à dire
(unsigned-int 64), ce qui est sbcl spécifique.
La version sans déclaration tourne quand même  1.7/0.8 soit 2 fois plus
vite que la version lua, ce qui est pas mal pour lua, je suppose que
python serait beaucoup plus lent (j'ai fait tourner https://
onecompiler.com/lua/42xp2gahe sur ma machine, en 1.7s).
Du coup j'ai fait tourner le programme avec N=10^9
  41.985 seconds of real time
  41.969659 seconds of total run time (41.957832 user, 0.011827 system)
  99.96% CPU
  62,838,884,786 processor cycles
  0 bytes consed
C'est bien.
Mon programme fortran de 15 lignes tourne en 0.50s (0.489 CPU) pour 10^9 :)

Pour aller plus vite il faut faire une boucle sur k=1,9 et une seconde
imbriquée entre \sqrt{10}*10^k et 10^{k+1}-1. On gagne automatiquement
au moins un facteur 0.684=1-\sqrt{10}/10. Ca remplace le test sur la
parité de k et les calculs qui concernent l.
Post by Michel Talon
Noter qu'aucun espace mémoire n'a été alloué dynamiquement sur le tas!
Je pense qu'on est là vers des performances proches du C. Peut être ça
peut convaincre certains que les très vieux langages, comme Common Lisp
(ou Fortran) ont des atouts non négligeables....
En effet.
--
F.J.
Michel Talon
2024-11-12 00:25:03 UTC
Permalink
Post by efji
C'est bien.
Mon programme fortran de 15 lignes tourne en 0.50s (0.489 CPU) pour 10^9
80 fois plus vite c'est quand même formidable! Vu que j'ai vérifié que
le programme compilé ne contenait que de l'assembleur x86 (pas d'appel
de fonction sauf pour l'écriture formattée) et est en outre assez court.
J'imagine bien que le compilateur fortran est beaucoup plus sioux et
utilise peut être des opérations vectorielles, aussi peut être ta
machine est beaucoup plus rapide que la mienne, ton algorithme meilleur,
etc de là à un facteur 80 c'est étonnant. Dans des essais que j'avais
fait, j'avais trouvé que le compilateur de sbcl donnait du code plus
performant sur les opérations flottantes que sur les entiers, en fait
des vitesses pratiquement égales entre du C et du lisp pour des calculs
flottants.
--
Michel Talon
efji
2024-11-12 08:45:53 UTC
Permalink
Post by efji
Post by Michel Talon
Du coup j'ai fait tourner le programme avec N=10^9
   41.985 seconds of real time
   41.969659 seconds of total run time (41.957832 user, 0.011827 system)
   99.96% CPU
   62,838,884,786 processor cycles
   0 bytes consed
C'est bien.
Mon programme fortran de 15 lignes tourne en 0.50s (0.489 CPU) pour 10^9 :)
Pour aller plus vite il faut faire une boucle sur k=1,9 et une seconde
imbriquée entre \sqrt{10}*10^k et 10^{k+1}-1. On gagne automatiquement
au moins un facteur 0.684=1-\sqrt{10}/10. Ca remplace le test sur la
parité de k et les calculs qui concernent l.
Note qu'en changeant simplement integer*8 en integer*16, pour pouvoir
monter plus haut en N, je passe de 0.5s à 11.97s pour la même valeur de
N. Un joli facteur 24.

La boucle la plus interne est on ne peut plus simple :

do i=n0,N-1
j = i*i
ia = j / n
ib = mod(j, n)
if (i .eq. ia + ib) write(*,'(i14,i25)') i,j
enddo
Une multiplication, une division, un modulo et un test.
Il doit y avoir moyen de se passer des entiers 128 bits qui sont
visiblement mal implémentés et de les remplacer par des tableaux
d'entiers 64 bits de taille 2. Il faudrait reprogrammer les 4 opérations
ci-dessus :
* multiplication : faire comme à l'école primaire mais pour un nombre à
2 "chiffres" de 64 bits, avec retenue.
* n=10^k -> division par n facile
* modulo n facile aussi
* test d'égalité: encore plus facile (test sur le 2eme élément du
tableau puis - très rarement - sur le 1er).

Au final il est peu probable que tout cela coûte 24 fois plus cher que
les mêmes calculs sur un seul entier.
--
F.J.
Olivier Miakinen
2024-11-09 18:43:21 UTC
Permalink
Post by efji
Post by Olivier Miakinen
Je reviens à JavaScript. Les indices de tableaux n'y sont *pas* des nombres
réels ! Même si les nombres entiers sont codés selon la norme IEEE 754 qui
peut *aussi* coder des nombres non entiers, seuls les entiers sont utilisés
comme indices de tableaux. Je crois même (mais c'est à vérifier) que seuls
les entiers positifs entre 0 et 2^32−1 sont autorisés comme index. Donc pas
3,14, ni −2, ni 2^42.
J'espère pour javascript que tu te trompes :)
Se limiter au 32 bits, donc 2GB de mémoire, en 2025 c'est carrément
pathétique.
Je parlais des index entiers. Mais en JavaScript tous les tableaux sont
associatifs, aussi je pense que tu peux avoir comme « index » des objets,
des chaînes de caractères, ou à peu près ce que tu veux.

Et dans un tableau tu peux aussi y mettre des tableaux. Alors un tableau
de 2^32 tableaux de 2^32 éléments, ça te fait 2^64 éléments au total.

Mais encore une fois, dans un langage interprété tel que JavaScript une
personne sensée ne va jamais tenter de remplir un tableau avec des milliards
de milliards d'éléments.
Post by efji
Post by Olivier Miakinen
Post by efji
Le truc embêtant c'est
qu'on perd toute la partie "exposant" du codage : en 64 bits la limite
est 2^53 = 9x10^15 au lieu de 2^63 = 9.2x10^18, on peut s'en contenter,
quoiqu'en adressage il ne soit pas impossible qu'on arrive rapidement à
cette valeur: 9x10^15 c'est 9000 terabits, soient 1000 TB. On y est presque.
Là tu trolles. Personne n'envisage d'indexer les bits ni même les bytes
d'un énorme disque dur en JavaScript. Tu disais toi-même à Thierry Loiseau
qu'il serait inenvisageable de chercher les nombres à l'origine de cette
enfilade au delà de 10^13 avec un langage interprété.
Il ne s'agit pas d'indexer un disque dur mais de la mémoire lorsqu'on
programme.
Quand bien même. Quel serait l'intérêt d'indexer dans un tableau chaque octet
individuellement ? Dans un tableau tu vas mettre des objets structurés de
plusieurs dizaines ou centaines d'octets, ou des références à d'autres
tableaux. Tu pourrais très bien utiliser toute la place disponible en
mémoire sans avoir besoin de plus d'une dizaine d'entrées utilisées dans
chacun de tes zillions de tableaux qui se référencent les uns les autres.
Post by efji
Je pensais que depuis l'expérience malheureuse de MS-Dos ("je
me demande bien qui un jour pourrait avoir besoin de plus de 640Ko de
mémoire") tout le monde avait compris que les mémoires utilisées étaient
en progression exponentielle sans horizon de stabilisation :)
Là tu parles de la numérotation, au plus bas niveau, de chacun des octets
existants. Pas d'un tableau dans un langage de programmation évolué, qui
plus est un langage de script.
Post by efji
Post by Olivier Miakinen
***
Mais je reviens à ta phrase du début « j'aurais du mal à prendre des indices
de tableaux comme des nombres réels » et à une phrase d'un de tes articles
précédents « il n'y a pas d'entiers en javascript ».
Nous sommes dans le groupe consacré aux mathématiques, fr.sci.maths. Est-ce
que tu considères qu'il n'y a pas d'entiers dans le corps des rationnels ou
dans le corps des réels ?
Ce n'est pas ce que je dis, j'ai juste dit que ça choque mes habitudes
de vieux, mais pourquoi pas si on y gagne quelque chose. Mais en fait je
ne vois pas ce qu'on y gagne :)
Ok. Ce qu'on y gagne, pour un langage de script, c'est que l'utilisateur
n'a pas besoin de jongler entre différents types de nombres comme par
exemple dans le langage C, avec des entiers 16, 32 et 64 bits, certains
signés et d'autres non signés, et des bugs incompréhensibles quand il ne
s'est pas rendu compte qu'ajouter un entier positif à un autre entier
positif le faisait devenir négatif, ou autre joyeuseté.

Avec IEEE 754, même en n'utilisant que des entiers, dépasser la capacité
après une opération peut donner comme résultat +∞ ou −∞, ce qui est
impossible avec des nombres entiers en complément à 2.
--
Olivier Miakinen
Julien Arlandis
2024-11-09 13:30:17 UTC
Permalink
Post by Olivier Miakinen
Post by efji
[les entiers comme un sous-ensemble des nombres IEEE 754 double précision]
En effet, ça peut se concevoir, même si c'est perturbant pour un vieux
comme moi. J'aurais du mal à prendre des indices de tableaux comme des
nombres réels, mais on doit pouvoir s'habituer.
Je reviens à JavaScript. Les indices de tableaux n'y sont *pas* des nombres
réels ! Même si les nombres entiers sont codés selon la norme IEEE 754 qui
peut *aussi* coder des nombres non entiers, seuls les entiers sont utilisés
comme indices de tableaux. Je crois même (mais c'est à vérifier) que seuls
les entiers positifs entre 0 et 2^32−1 sont autorisés comme index. Donc pas
3,14, ni −2, ni 2^42.
Pas sûr de ça, Javascript mélange les tableaux indexés et les tableaux
associatifs, ainsi que le montre cet exemple :

a = [5, 6, 12, 10] // => [5, 6, 12, 10]
a[3.14] = 66 // => [5, 6, 12, 10, 3.14: 66]
efji
2024-11-09 14:54:41 UTC
Permalink
Post by Julien Arlandis
Post by Olivier Miakinen
comme indices de tableaux. Je crois même (mais c'est à vérifier) que seuls
les entiers positifs entre 0 et 2^32−1 sont autorisés comme index. Donc pas
3,14, ni −2, ni 2^42.
Pas sûr de ça, Javascript mélange les tableaux indexés et les tableaux
a = [5, 6, 12, 10] // => [5, 6, 12, 10]
a[3.14] = 66 // => [5, 6, 12, 10, 3.14: 66]
Petit test en fortran qui est très permissif:

x = 2.e5/3.
iy(x) = 1

-> warning à la compilation mais le programme tourne et met la valeur 1
en position 66666 du tableau, qui est la partie entière de x.
--
F.J.
Olivier Miakinen
2024-11-09 19:03:20 UTC
Permalink
Post by Julien Arlandis
Post by Olivier Miakinen
Je reviens à JavaScript. Les indices de tableaux n'y sont *pas* des nombres
réels ! Même si les nombres entiers sont codés selon la norme IEEE 754 qui
peut *aussi* coder des nombres non entiers, seuls les entiers sont utilisés
comme indices de tableaux. Je crois même (mais c'est à vérifier) que seuls
les entiers positifs entre 0 et 2^32−1 sont autorisés comme index. Donc pas
3,14, ni −2, ni 2^42.
Pas sûr de ça, Javascript mélange les tableaux indexés et les tableaux
a = [5, 6, 12, 10] // => [5, 6, 12, 10]
a[3.14] = 66 // => [5, 6, 12, 10, 3.14: 66]
Oui, j'ai fait un raccourci en disant « seuls les entiers sont utilisés
comme indices de tableaux », car on peut avoir des « index » qui ne sont
pas des entiers. Mais même les tableaux associatifs sont limités à une
taille de 2^32−1 éléments car en interne ils sont indexés par un entier
sur 32 bits :

https://www.google.com/search?q=taille+max+d%27un+tableau+en+javascript
</cit>
Les tableaux JavaScript sont basés sur zéro et utilisent des index 32 bits :
l'index du premier élément est 0 et l'index le plus élevé possible est
4294967294 (2^32 −2), pour une taille de tableau maximale de 4 294 967 295 éléments.
</cit.>

Les nombres non entiers, ou trop grands, sont transformés en chaînes de
caractères quand on tente de les utiliser comme index :

a = [5, 6, 12, 10] // => [5, 6, 12, 10]
a[3.14] = 66 // => [5, 6, 12, 10, '3.14': 66]
a[5000000000] = 42 // => [ 5, 6, 12, 10, '3.14': 66, '5000000000': 42 ]
a[4000000000] = 41 // => [ 5, 6, 12, 10, <3999999996 empty items>, 41,
// '3.14': 66, '5000000000': 42 ]
--
Olivier Miakinen
Thomas Alexandre
2024-11-10 10:00:44 UTC
Permalink
Post by Olivier Miakinen
Je reviens à JavaScript. Les indices de tableaux n'y sont *pas* des
nombres réels ! Même si les nombres entiers sont codés selon la norme
IEEE 754 qui peut *aussi* coder des nombres non entiers, seuls les
entiers sont utilisés comme indices de tableaux. Je crois même (mais
c'est à vérifier) que seuls les entiers positifs entre 0 et 2^32−1 sont
autorisés comme index. Donc pas 3,14, ni −2, ni 2^42.
Alors si et c'est même bien pire que ça :

```js
let a = []
a[Math.PI] = 3.14
a[-Math.PI] = -3.14
a["π"] = 3.14
a[true] = 1
a[null] = 0
a[false] = -1
a[NaN] = 42
console.log(a)
```

Personnellement je trouve que c'est à vomir. Ce n'est pas pour rien qu'il y
a TypeScript¹ (pourquoi faire simple alors qu'on peut rajouter une
couche ?).

¹: https://www.typescriptlang.org


xpost et fu2 fr.comp.lang.javascript
--
"Ce qu'il faut au fond pour obtenir une espèce de paix avec les hommes,
(...) c'est leur permettre en toutes circonstances, de s'étaler, de se
vautrer parmi les vantardises niaises. Il n'y a pas de vanité
intelligente. C'est un instinct." - Céline
Olivier Miakinen
2024-11-08 08:51:46 UTC
Permalink
Post by Thierry Loiseau
Post by efji
Post by Olivier Miakinen
Post by Thierry Loiseau
V[81] = 8 + 1 = 9
V[2025] = 20 + 25 = 45
V[3025] = 30 + 25 = 55
V[494209] = 494 + 209 = 703
V[998001] = 998 + 001 = 999
*********************************************************************
Ça c'est amusant. Je suppose qu'il a listé tous les exemples de moins de
de moins de _sept_ chiffres
Je me suis laissé influencer par des youtubeurs anglophones pour qui
« less than » signifie « inférieur ou égal ».

Soit dit en passant, ils n'y étaient pas tous. Par exemple il manquait
99² = 9801
Post by Thierry Loiseau
Post by efji
Post by Olivier Miakinen
1) Est-ce qu'il existe un plus grand nombre ayant cette propriété, ou
bien est-ce qu'on peut en trouver une infinité ?
999 998001
4950 24502500
5050 25502500
9999 99980001
99999 9999800001
499500 249500250000
500500 250500250000
999999 999998000001
(je n'ai laissé ci-dessus que ceux qui illustrent mon propos ci-dessous)
Post by Thierry Loiseau
Post by efji
Il y a tous les (10^n)-1 déjà, et puis aussi les 5*(1+10^{n+1})*10^n.
Donc une infinité.
*Bravo* ! Je ne sais pas comment vous avez établi ces formules...
Dans la liste que tu as donnée, puis celle complétée par F.J., on repère
certaines régularités :
− 9, (99,) 999, 9999, 99999, 999999
− 45, 4950, 499500
− 55, 5050, 500500

Il n'y a plus qu'à vérifier par le calcul que cela fontionne toujours.
--
Olivier Miakinen
Loading...