Arrondi au multiple, plafond, plancher

C’est un portage en 4D de fonctions du tableurs, utiles quand on veut faire des arrondis tels que “à l’euro supérieur”, “au 10 centimes inférieurs”.
<code 4D>
//Num_MRound (nombre_r;palier_r { ;plafondOuPlancher_l) -> réel
//arrondi multiple de nombre (arrondi par palier)
//$3 optionnel plafondOuPlancher_l :
// 0 ou non passé = arrondi multiple (défaut)
// >0 = plafond
// <0 = plancher
//ex :
// Euro le plus proche := Num_MRound (nombre;1)
// 10 cts supérieurs := Num_MRound (nombre;0,1;1)
// 5 cts inférieurs := Num_MRound (nombre;0,05;-1)

C_REEL($0)
C_REEL($1)
C_REEL($2)
C_ENTIER LONG($3)

C_REEL($out_r)
C_REEL($nombre_r)
C_REEL($multiple_r)
C_ENTIER LONG($proche_l)

C_REEL($modulo_r)
C_ENTIER LONG($params_l)

Si (Faux)
C_REEL(Num_MRound ;$0)
C_REEL(Num_MRound ;$1)
C_REEL(Num_MRound ;$2)
C_ENTIER LONG(Num_MRound ;$3)
Fin de si
//_
$params_l:=Nombre de parametres
ASSERT($params_l>1;Nom methode courante)
ASSERT($2#0;Nom methode courante)
$nombre_r:=$1
$multiple_r:=$2
$proche_l:=0
Si ($params_l>2)
$proche_l:=$3
Fin de si

$modulo_r:=Num_modulo ($nombre_r;$multiple_r) //modulo façon tableur
Au cas ou
: ($proche_l=0) //arrondi multiple
Si ($modulo_r>($multiple_r/2))
$out_r:=$nombre_r-$modulo_r+$multiple_r
Sinon
$out_r:=$nombre_r-$modulo_r
Fin de si
: ($proche_l>0) //plafond
Si ($modulo_r=0)
$out_r:=$nombre_r
Sinon
$out_r:=$nombre_r-$modulo_r+$multiple_r
Fin de si
: ($proche_l<0) //plancher
$out_r:=$nombre_r-$modulo_r
Fin de cas
$0:=$out_r
//_
</code 4D>

<code 4D>
//Num_modulo (dividende_r;diviseur_r) -> reel
//$0 modulo du tableur
//marche avec dividende et diviseur décimaux
//basé sur calcul avec la partie entière E
//https://fr.wikipedia.org/wiki/Modulo_(opération)
C_REEL($0)
C_REEL($1)
C_REEL($2)

C_REEL($modulo_r)
C_REEL($div_r)
C_REEL($nombre_r)
C_REEL($t_r)

$nombre_r:=$1
$div_r:=$2
$t_r:=Troncature($nombre_r/$div_r;0)
$modulo_r:=$nombre_r-($div_r*$t_r)
$0:=$modulo_r

//_
</code 4D>

ça permet aussi de générer des http://www.lettredesreseaux.com/P-599-678-P1-prix-rompu.htmlprix magiques> :
<code 4D>
AJOUTER A TABLEAU($_ar;1)
AJOUTER A TABLEAU($_ar;10)
AJOUTER A TABLEAU($_ar;50)
AJOUTER A TABLEAU($_ar;100)
AJOUTER A TABLEAU($_ar;500)
AJOUTER A TABLEAU($_ar;1000)
Boucle ($i_l;1;Taille tableau($_ar))
$_ar{$i_l}:=Troncature(Num_MRound ($_ar{$i_l};0,9999999);2)
Fin de boucle
</code 4D>

Autre déclinaison du modulo…

Dans un tableur, la colonne 4 est ce qu’on cherche à obtenir :
[]23095970;“Your comment here…”[/]

Converti en 4D :
<code 4D>
//Num_modNotNul (nombre_l;diviseur_l) -> long
//retourne le “modulo non nul” de l’opérateur %
//i.e. si modulo vaut 0, on retourne le diviseur
//
//#nota
// la formule tableur pour le même résultat :
// =MOD(nombre;-diviseur)+(diviseur-1)
// non utilisable dans 4D qui commence par
// passer le diviseur en positif
C_ENTIER LONG($0)
C_ENTIER LONG($1)
C_ENTIER LONG($2)

C_ENTIER LONG($diviseur_l)
C_ENTIER LONG($mod_l)
C_ENTIER LONG($nbre_l)

Si (Faux)
C_ENTIER LONG(Num_modNotNul ;$0)
C_ENTIER LONG(Num_modNotNul ;$1)
C_ENTIER LONG(Num_modNotNul ;$2)
Fin de si

//_
ASSERT(Nombre de parametres>1;Nom methode courante+" 2 params expected")
$mod_l:=0
$nbre_l:=$1
$diviseur_l:=$2
$mod_l:=$nbre_l%$diviseur_l
Si ($mod_l=0)
$mod_l:=$diviseur_l
Fin de si
$0:=$mod_l
//_

</code 4D>

Dans 4d, ça peut servir par exemple à ça :
<code 4D>
//Avec 4D, le jour 1 de la semaine est dimanche
// mais nous les frenchies on préfère lundi
//Le code suivant permet avec Ajouter a date de
// calculer début et fin de semaine d’une date
$date_d:=Date du jour-14
Boucle ($i_l;1;14)
$numJour_l:=Numéro du jour($date_d)
$numJourFr_l:=Num_modNotNul ($numJour_l-1;7) //la semaine commence lundi
$debutSemaine_d:=Ajouter à date($date_d;0;0;-$numJourFr_l)+1
$finSemaine_d:=$debutSemaine_d+6
ASSERT($debutSemaine_d<=$date_d)
ASSERT($finSemaine_d>=$date_d)
ASSERT(numero du jour($debutSemaine_d)=lundi)
ASSERT(numero du jour($finSemaine_d)=dimanche)
$date_d:=$date_d+1
Fin de boucle
</code 4D>
ou à ça :
<code 4D>
$debutExerciceCompta_d:=Ajouter à date(!00/00/0000!;2011;Juin;1)
$offset_l:=Mois de($debutExerciceCompta_d)+1
ASSERT(Num_modNotNul (Juin+$offset_l;12)=1)
ASSERT(Num_modNotNul (Novembre+$offset_l;12)=6)
ASSERT(Num_modNotNul (Mai+$offset_l;12)=12)
</code 4D>
ou à ne pas diviser par zéro.