CoddyRun

Support public · Bugs

Résolu

arrondi_inferieur(puissance(2, 53)/60) retourne un négatif

Ouvert par Freecrazy le 5 novembre 2026 · 9 messages · 25 vues

Ce sujet est résolu.
Freecrazy Développeura ouvert le sujet 5 novembre 2026 à 11h30

tout est dans le titre, mais pour être encore plus précis :

affiche arrondi_inferieur(puissance(2, 53) / 60) --> -2004318072 ??

alors que

affiche arrondi(puissance(2, 53) / 60) --> 150119987579017 la bonne valeur

Peut-être que certains diront d'utiliser arrondi mais dans ce cas

affiche arrondi(3/5) --> 1
affiche arrondi_inferieur(3/5) --> 0

et c'est bien le arrondi_inferieur dont j'ai besoin pour avoir l'équivalent de la division entière

Bonjour Freecrazy,

Merci d'avoir remonté le problème, c'est intriguant.

Je regarde ça en fin de journée et je reviendrai sur le forum avec une explication sur l'origine de ce bug et ce qui provoque ce résultat inattendu.

Apprendre à coder, c'est avant tout apprendre à penser.

Oui, je reconnais que c'est assez curieux, peut-être lié à la représentation binaire des grands nombres.
En attendant j'ai contourné le problème en faisant une division entière a/b comme ceci :

(a - a % b)/b

Merci pour le signalement, c'était bien un bug de CoddyRun et pas une erreur de ta part.

En interne, arrondi_inferieur (et aussi arrondi_superieur) convertissait le résultat en entier 32 bits.
Au-delà d'environ 2,1 milliards, le nombre débordait et devenait négatif, d'où le -2004318072. arrondi n'était pas touché parce qu'il utilise des entiers 64 bits.

C'est corrigé pour la prochaine version : les deux fonctions fonctionnent maintenant sur des nombres de n'importe quelle taille.

affiche arrondi_inferieur(puissance(2, 53) / 60)  --> 150119987579016
affiche arrondi_inferieur(3/5)  --> 0

À noter : le résultat finit bien par 6 et non par 7 comme avec arrondi, puisque la valeur exacte est 150119987579016,53…

Encore merci Freecrazy !

Apprendre à coder, c'est avant tout apprendre à penser.

Bien vu, ta formule fonctionne.

Petite précision : avec des nombres négatifs, ta formule arrondit vers zéro au lieu d’arrondir vers le bas (-7 et 2 donnent -3 au lieu de -4). Voici une version qui gère tous les cas :

fonction division_entiere(x, b)
  r vaut x % b
  q vaut (x - r) / b
  si r * b < 0 alors
    q vaut q - 1
  fin si
  retourne q
fin fonction

affiche division_entiere(puissance(2, 53), 60)
affiche division_entiere(3, 5)
affiche division_entiere(-7, 2)

Résultats : 150119987579016, 0, -4.

Le si corrige le cas où le reste et le diviseur sont de signes opposés : c’est exactement là que l’arrondi vers zéro et l’arrondi vers le bas donnent des résultats différents.

Apprendre à coder, c'est avant tout apprendre à penser.

Freecrazy a écrit :

En testant un peu les choses se gâtent vers 2^35 selon le diviseur. Pas top !

C’est le même bug : arrondi_inferieur se trompait dès que le résultat de la division dépassait 2 147 483 647 (limite d’un entier 32 bits).

C’est pour ça que ça dépend du diviseur : avec 2^35, ça casse pour tout diviseur inférieur à 16.
Parfois le résultat est négatif, parfois il est juste faux (2^35 / 7 donnait 613566756 au lieu de 4908534052).

C’est corrigé dans la prochaine version.

Si tu as vu le problème avec ta formule (a - a % b) / b et pas avec arrondi_inferieur, envoie-moi l’expression exacte et les valeurs, je regarderai.

Merci Freecrazy.

Apprendre à coder, c'est avant tout apprendre à penser.

J'avais bien pensé à un problème de représentation binaire des grands nombres mais je n'ai pas pensé à un passage de 64 bits en 32 bits.
Bon, le tout est que cela soit réglé.

le résultat finit bien par 6 et non par 7 comme avec arrondi

Oui je suis d'accord, je me suis un peu mélangé les pinceaux. Comme cette transformation était à l'intérieur d'un programme plus gros avec des boucles, j'ai mis un peu de temps avant de trouver le problème : pour certaines valeurs mon programme fonctionnait mais pas pour d'autres ...

avec des nombres négatifs, ta formule arrondit vers zéro au lieu d’arrondir vers le bas

Oui j'ai fait au plus vite car je ne traite que les nombres positifs et je n'ai pas fait de fonction générale. Et pour l'instant tous mes tests passent avec ma formule :-)

C’est corrigé dans la prochaine version.

Ok, je vais attendre alors avant de modifier. Ceci étant je ne sais pas ce qui est le plus rapide pour les positifs ma formule ou avec l'arrondi. Je n'ai pas encore creusé la question sous CoddyRun. D'ailleurs je doute qu'il y ait possibilité de tester les temps d'exécution, non ?.

Bonjour Freecrazy,

D'ailleurs je doute qu'il y ait possibilité de tester les temps d'exécution, non ?.

Si vous avez une fonction chrono() qui mesure le temps d'exécution d'un bloc de code ou d'un programme en millisecondes.

Exemple :

// Mesurer le temps d'exécution d'un bloc
tdebut est un nombre
tdebut vaut chrono()

// ... code à mesurer ...
somm est un nombre
pour i de 1 à 180000
  somm ajoute i
fin pour

tfin est un nombre
tfin vaut chrono()
affiche 'Temps : ' + convertir_texte(tfin - tdebut) + ' ms'

FAQ : Comment mesurer le temps d'exécution d'un morceau de code ?
https://coddyrun.fr/faq/?q=313

Apprendre à coder, c'est avant tout apprendre à penser.
Une question ? Connectez-vous pour ouvrir votre propre sujet : CoddyRun vous répondra. La création d'un compte est gratuite et prend une minute.