Comparer entiers très long

Je dois déterminer le plus grand de deux chaines représentant des entiers qui ont trop de chiffres significatifs pour 4D, par exemple :
125656535228786
125835254264217
Un bout de code ?
(j’ai bien une idée de comment faire, mais ne pas ré inventer la roue m’arrangerait…)

S’il n’y a que des chiffres dans les chaînes, quelque chose comme ça :
<code 4D>
((“0”(50-Longueur($chaine)))+$chaine)>((“0”(50-Longueur($chaine2)))+$chaine2)
</code 4D>

Merci Stan, c’est parfait :slight_smile:
Je refais le couplet sur “qu’est-ce que ça manque les entiers 64.”

Tant qu’à faire :
<code 4D>
//Str_plusGrandEntier (entier1_t;entier2_t) -> ent
//Détermine le plus grand de 2 nombres entiers sous forme de chaine,
//trop grands pour une comparaison mathématique
//$0 :
// 1 = $1 est le plus grand
// -1 = $2 est le plus grand
// 0 = les nombres sont égaux ou non comparables
C_ENTIER LONG($0)
C_TEXTE($1;$2)
//_
$out_l:=0
$ent1_t:=$1
$ent2_t:=$2
$rx_t:="\D" //un “non chiffre”
Si (Non(Trouver regex($rx_t;$ent1_t;1)))
Si (Non(Trouver regex($rx_t;$ent2_t;1)))
//virer les éventuels 0 à gauche
Tant que (Trouver regex("^0{1,50}";$ent1_t;1;$pos_l;$len_l))
$ent1_t:=Sous chaîne($ent1_t;$pos_l+$len_l)
Fin tant que
Tant que (Trouver regex("^0{1,50}";$ent2_t;1;$pos_l;$len_l))
$ent1_t:=Sous chaîne($ent2_t;$pos_l+$len_l)
Fin tant que
$len1_l:=Longueur($ent1_t)
$len2_l:=Longueur($ent2_t)
Au cas ou
: ($len1_l>$len2_l)
$out_l:=1
: ($len1_l<$len2_l)
$out_l:=-1
: ($ent1_t>$ent2_t)
$out_l:=1
: ($ent1_t<$ent2_t)
$out_l:=-1
Fin de cas
Fin de si
Fin de si
$0:=$out_l
</code 4D>

n’empêche qu’avec des entiers 64 gna gni gna gni gna…

Pour ta regex qui vérifie qu’il n’y a que des chiffres, il serait, à mon avis, plus rapide de chercher un caractère qui ne soit pas un chiffre.
Donc Non(Trouver regex("\D";…)) tout simplement.

Bonne idée - j’oublie toujours d’être négatif :slight_smile:
Corrigé dans l’original.

: Bruno LEGAY

Enfin, si tu mets ça dans un composant, la table [xxx_empty] ne sera
même pas visible…

Qu’en penses-tu ?

Bonjour Bruno,

il me semble qu’un composant ne possède pas de table, sauf si il accède à un fichier de données externe par SQL.
Je me trompe?

Patrick

I have a raw example for + - * (no division sorry I am lazy)

https://github.com/miyako/4d-tips-text-integer-maths

there is also PHP BCMath http://www.php.net/manual/en/book.bc.php

: Bruno LEGAY

Qu’en penses-tu ?
Bin, là, je suis moyen séduis (ce qui m’est inhabituel avec toi, je te rassure).

La perspective de passer par une table “tampon” et de créer un enregistrement pour un calcul ne m’enchante pas. Mais, surtout, je crains que le principe coince sur les lignes 35 à 38, car si je passe à Num un nombre qui dépasse les 13 chiffres significatifs, cette fonction, le convertissant en réel 4D, le charcute par la même occasion.
[]26319849;“Your comment here…”[/]

Cela dit ton idée m’en donne une autre, convertir ces entiers 64 en uuid : déterminer le plus grand serait archifacile. Mais je ne sais pas convertir une telle chaine décimale en hexa.

Par curiosité, j’ai regardé la fonction DECHEX (conversion dec vers hexa) d’un tableur :
[]26320084;“Your comment here…”[/]
J’imagine qu’il traite les numériques sur 64 bits avec un bit de signe (?). En tout cas DECHEX part en sucette à 2^40 et la représentation non scientifique semble plafonner à 16 chiffres significatifs.

J’ai regardé aussi coté SQL : j’ai appris à stoker des entiers 64 (newbie total), mais n’arrive pas à les lire en hexa avec CAST. Par contre je remarque que ce champ, simplement placé dans un form sortie en utilisation directe affiche tous les chiffres de ces grands nombres : étonnant, non ?
[]26321217;“Your comment here…”[/]

Bonjour,

: Arnaud DE MONTARD

La perspective de passer par une table “tampon” et de créer un
enregistrement pour un calcul ne m’enchante pas.
Je pense (à vérifier) que quand 4D créée un enregistrement, il est simplement créé en mémoire (tant qu’il n’est pas stocké). Je suis parti avec cette hypothèse qu’il faudrait vérifier…

: Arnaud DE MONTARD

Mais, surtout, je crains que le principe coince sur les lignes 35 à
38, ar si je passe à Num un nombre qui dépasse les 13 chiffres
significatifs, cette fonction, le convertissant en réel 4D, le
charcute par la même occasion…
Ben, du coup, c’est mort…

Un plugin ?

: Bruno LEGAY

Ben, du coup, c’est mort…
Un plugin ?
Je n’y connais rien en plugins : si ce sont des données stockées en ent64, est-ce qu’il permettra de les lire ? Les nombres que j’ai donnés en exemple viennent d’autres systèmes (logiciels de paie) ; je stocke en alpha, vu ma nullité en SQL…

En même temps, cette liste d’entiers 64bits qui s’affiche avec plus de chiffres significatifs que le langage n’en autorise, je me demande si ça ne signifie pas que c_entierArchiLong n’est pas sur les rails. Bon, si ça se trouve, c’est comme ça depuis la v11, je viens de le remarquer.

this is a quick proof of concept:

https://github.com/miyako/4d-plugin-mapm

(mac only for now…)

Miyako, I’m stunned!
Moreover it seems fast, I just made a rapid comparison with 4D similar operators:
<code 4D>
$r:=""
$a:=“10000000000000000000.00000000000000000001”
$b:=“10000000000000000000.00000000000000000001”
$aa:=100,0001
$bb:=100,0001
$count1_l:=0
$end_l:=Nombre de ticks+(120)
Repeter
$count1_l:=$count1_l+1
$zz:=$aa+$bb
$zz:=$aa-$bb
$zz:=$aa*$bb
Jusque (Nombre de ticks>$end_l)
$count2_l:=0
$end_l:=Nombre de ticks+(120)
Repeter
$count2_l:=$count2_l+1
m_apm_add ($r;$a;$b) //20000000000000000000.00000000000000000002
m_apm_subtract ($r;$a;$b) //0
m_apm_multiply ($r;$a;$b) //100000000000000000000000000000000000000.2000000000000000000000000000000000000001
Jusque (Nombre de ticks>$end_l)
</code 4D>
$count1_l=283497
$count2_l=20593
About ~14 times slower: not bad for such numbers!!!

Makes me remember when I was a student, I worked all the time with power of 10 numbers…

PS
If some are interested, it’s worth reading https://github.com/LuaDist/mapmthis>.

PS2
:clap::clap::clap: :wink:

I’ve added Windows support: :mrgreen:

https://github.com/miyako/4d-plugin-mapm/releases/tag/1.0

: Keisuke MIYAKO

I’ve added Windows support: :mrgreen:
I have to buy a pc… :lol:

Je n’avais pas remarqué cette note de la doc de http://doc.4d.com/4Dv17/4D/17/CAST.300-3786721.en.htmlCAST>:
“Note: The CAST function is not compatible with “Integer 64 bits” type fields in compiled mode.”
Si on ne peut pas transtyper un int64 en alphanumérique avec CAST en compilé, comment le lire sans risquer de perdre des chiffres significatifs ? Allez, on vérifie : test de lecture SQL en v17 compilée de mes 2 nombres à 15 digits dans un champ int64…
<code 4D>
TABLEAU TEXTE($_at;0)
Début SQL
SELECT CAST (int64bits AS ALPHA_NUMERIC)
FROM Table1
INTO :$_at;
Fin SQL
ASSERT($_at{1}=“125656535228786”)
ASSERT($_at{2}=“125835254264217”)
</code 4D>
–> aucune différence en interprété et en compilé.

Je commence à être perdu : CAST est plus fort que la doc ou quelque chose m’échappe ?