Page 1 sur 1

Problème avec round()

Posté : 23 avr. 2009, 10:18
par Cobra52
Bonjour à tous,

J'ai un soucis avec round().
J'utilise :
// où $amount = '1.204';
// et $sql_select['tHT'] = '0.931';

$total_ht = round($amount + $sql_select['tHT'], 2);

// donc :
// $total_ht = '2.135';
// avec round() $total_ht devrait être = '2.14';
Dans ma table, le champ total_ht = double; 16,2
Mais cela m'insère '2.13' au lieu de '2.14'

Je ne vois pas d'où peut provenir le problème.
Merci pour votre aide :wink:

Posté : 23 avr. 2009, 11:04
par D4Y
C'est normal que tu sois à 2.13 car pour etre au supérieur tu devrais avoir 2.136 et non 2.135 !

<?php
function ceiling($value, $precision = 0) {
return ceil($value * pow(10, $precision)) / pow(10, $precision);
}
?>

Posté : 23 avr. 2009, 11:09
par Cobra52
C'est normal que tu sois à 2.13 car pour etre au supérieur tu devrais avoir 2.136 et non 2.135 !
Non, je ne crois pas, avec '2.135' on devrait bien passer à '2.14', arrondi supérieur à partir de 5.

Pris sur phpmanuel :
echo round(5.045, 2);    // 5.05

Posté : 23 avr. 2009, 11:16
par Ryle
C'est un bug sans en être un... En fait la fonction round() lorsqu'elle est utilisée pour arrondir des nombres qui tombent exactement sur le demi va arrondir les pairs à l'inférieur et les impairs au supérieur.
echo round(1.135, 2);    // 1.14
echo round(2.135, 2);    // 2.13
echo round(3.135, 2);    // 3.14
La raison de ce comportement (pour le moins abérant selon moi) est financier et absolument pas mathématique, afin de ne pas toujours arrondir au supérieur et ainsi prélever un peu plus d'argent, ou perdre un peu plus d'argent à chaque fois que tu vas arrondir. Ca permet d'espérer avoir un compte qui en moyenne devrait avec un peu de chance rester équilibré (et je vous ferais grace de mon avis en la matière).

Ca avait été "corrigé" avec php 4.3, c'est revenu avec php 5.0 ...

Posté : 23 avr. 2009, 11:28
par Cobra52
Merci pour vos réponses :wink:

J'ai fait une fonction :
function round2($number, $round = 2)
	{
		$temp_value = $number * pow(10, $round);
		$temp_value = ceil($temp_value);
		$number = $temp_value / pow(10, $round);

		return $number;
	}
L'insertion est bonne dans ma table avec '2.14'
Pensez-vous que je peux utiliser cette fonction sans risque ?

Merci.

EDIT :
Ah ben non, ça ne fonctionne pas non plus avec :
'0.262' c'est arrondi à '0.27' !
J'ai essayé aussi avec la fonction de D4Y, même résultat.

Posté : 23 avr. 2009, 15:11
par Ryle
Une astuce à la c** mais qui fonctionne :
echo round(2.135 + 0.0000001, 2);    // 2.14

Posté : 23 avr. 2009, 15:24
par Cobra52
Une astuce à la c** mais qui fonctionne :
echo round(2.135 + 0.0000001, 2);    // 2.14
Il n'y a aucun risque à utiliser ça ? ça fonctionne à 100% ?

Errfffff, va falloir que je modifie l'ensemble du script, suis pas sorti de l'auberge :lol:

Posté : 23 avr. 2009, 15:36
par Ryle
J'avous ne pas avoir essayé plus que ça... j'imagine que ça doit probablement dépendre de ton nombre de décimales et des valeurs de celles-ci, encore que même avec un :
echo round(1.13444444 + 0.0000001, 2);    // 1.13
J'obtiens bien 1.13 en arrondissant...

Quant à modifier l'ensemble du script, suffit juste de changer ta fonction round2() :)

Posté : 23 avr. 2009, 15:46
par Cobra52
J'avous ne pas avoir essayé plus que ça... j'imagine que ça doit probablement dépendre de ton nombre de décimales et des valeurs de celles-ci, encore que même avec un :
echo round(1.13444444 + 0.0000001, 2);    // 1.13
J'obtiens bien 1.13 en arrondissant...

Quant à modifier l'ensemble du script, suffit juste de changer ta fonction round2() :)
Ok, je tente ça.
Quant à modifier ma fonction, euh ... là je suis un peu pommé :oops:

EDIT :
si je fais uniquement ça, c'est bon ?
function round2($number, $round = 2) 
{ 
        $number = ($number + 0.0000001, $round);

        return $number; 
}
Merci.

Posté : 23 avr. 2009, 15:50
par thehawk
function round2($number, $round = 2)
    {
        $number = round($number + 0.0000001, $round);

        return $number;
    } 
Surement quelque chose de ce genre ^^

Posté : 23 avr. 2009, 15:51
par Ryle
Bah basiquement :
function round2($number, $round = 2) { 
        return round($number + 0.0000001, $round); 
}
Maintenant tu dois pouvoir faire un truc un peu plus propre et gérer le nombre de 0 en fonction de $round .... c'était juste histoire de centraliser l'arrondi pour que si jamais tu trouvais mieux, t'ai pas à repasser partout :)

Posté : 23 avr. 2009, 15:55
par Cobra52
Bah basiquement :
function round2($number, $round = 2) { 
        return round($number + 0.0000001, $round); 
}
Maintenant tu dois pouvoir faire un truc un peu plus propre et gérer le nombre de 0 en fonction de $round .... c'était juste histoire de centraliser l'arrondi pour que si jamais tu trouvais mieux, t'ai pas à repasser partout :)
Oups, j'ai posté mon "EDIT" en même temps que vous, et avec une erreur grosse comme moi !

Merci à vous pour votre aide :D
Je me lance avec ça.

Posté : 28 avr. 2009, 14:40
par Cobra52
Une dernière question.

Je travaille en local avec Easyphp, php5, mysql5

J'insère, dans ma bdd, des montant de tva à 3 chiffres après la virgule (tels qu'ils sont générés par php), qui semblent respecter les règles d'arrondi.
Est-ce normal ?

Merci à vous.

EDIT : en fait, non, c'est le même problème !