OVH Cloud OVH Cloud

Fonction Int

8 réponses
Avatar
bcar
Bonjour,

si on fait sous excel( 2000-2002-XP ) (win200, XP)

sub test()
Dim x as Long

x = Int(37.7266 * 10000)
' on obtient x = 377265
' je m'attendais à avoir 377266

' par contre si on fait
x = int(37.7263 * 10000)
' on obtient bien x = 377263
end sub

En fait 37.7263 donne le résultat que j'attends, 37.7264, non, 37.7265,
ok, ....

Avez vous une explication ?

8 réponses

Avatar
Daniel
Bonjour.
Cela arrive rarement, mais cela arrive. Cela tient au fait que Excel, comme
tous les programmes effectue les calcules en binaire et doit convertir les
nombres décimaux en binaire avant de calculer. Si 37,7266 traduit en binaire
puis redraduit en décimal donne 37,726599999999 (par exemple), la
mutiplication donne 377265,99999999 et la fonction Ent donne 377265.
Cordialement.
Daniel
"bcar" a écrit dans le message de news:
en2lib$aj0$
Bonjour,

si on fait sous excel( 2000-2002-XP ) (win200, XP)

sub test()
Dim x as Long

x = Int(37.7266 * 10000)
' on obtient x = 377265
' je m'attendais à avoir 377266

' par contre si on fait
x = int(37.7263 * 10000)
' on obtient bien x = 377263
end sub

En fait 37.7263 donne le résultat que j'attends, 37.7264, non, 37.7265,
ok, ....

Avez vous une explication ?


Avatar
JièL
Bonjoir(c) bcar

effectivement, comme le démontre Daniel, le VBA est nul en calcul !
mais... Excel lui ne se plante pas sur ce genre de truc (encore heureux !!!)

essayez ça
x = [Int(37.7266 * 10000)]
ou (plus long mais plus explicite)
x = Evaluate("Int(37.7266 * 10000)")

en gros ça veut dire : steuplé Excel, tu veux bien me calculer cette
formule et me donner le bon résultat ? Mon pote VBA sait pas faire
;-)

voir l'explication sur Evaluate dans l'aide

--
JièL / Jean-Louis GOUBERT - Bonnes fêtes de fin d'année
Là bas mieux qu'en face ;-) http://forums.offices.free.fr/
La FAQ Outlook est là : http://faq.outlook.free.fr/
Les stats de CDO : http://faq.outlook.free.fr/cdo/

Le 29/12/2006 10:30 vous avez écrit ceci :
Bonjour,

si on fait sous excel( 2000-2002-XP ) (win200, XP)

sub test()
Dim x as Long

x = Int(37.7266 * 10000)
' on obtient x = 377265
' je m'attendais à avoir 377266

' par contre si on fait
x = int(37.7263 * 10000)
' on obtient bien x = 377263
end sub

En fait 37.7263 donne le résultat que j'attends, 37.7264, non, 37.7265,
ok, ....

Avez vous une explication ?


Avatar
MichDenis
Pour éviter l'inconvénient, utilise une variable
Dim X
X = 37.7266 * 10000
a = Int(X)





"bcar" a écrit dans le message de news: en2lib$aj0$
Bonjour,

si on fait sous excel( 2000-2002-XP ) (win200, XP)

sub test()
Dim x as Long

x = Int(37.7266 * 10000)
' on obtient x = 377265
' je m'attendais à avoir 377266

' par contre si on fait
x = int(37.7263 * 10000)
' on obtient bien x = 377263
end sub

En fait 37.7263 donne le résultat que j'attends, 37.7264, non, 37.7265,
ok, ....

Avez vous une explication ?
Avatar
Daniel
mais... Excel lui ne se plante pas sur ce genre de truc (encore heureux
!!!)

Salut JièL,

Ca m'est arrivé avec XL97, il y a quelques années. Le calcul (je ne me
rapelle plus quel il était) était juste ou faux selon qu'il était posé
simplement ou à l'intérieur d'une condition (SI). Cela dépendait égélement
de la ligne sur laquelle il était effectué ! Transmis à Microsoft, je n'ai
jamais eu de nouvelles - ni de T-shirt ;-((
Daniel

Avatar
MichDenis
Ceci est aussi possible en utilisant des variables

A = 37.7266
B = 10000
X = Int(A * b)
Résultat obtenu = 377266

Supposons que l'on définisse le type des variables comme suit :
Dim x
Dim A As Double, B As Integer
A = 37.7266
B = 10000
x = Int(A * B)
Résultat obtenu = 377265

Je n'ai pas l'explication...mais le truc de transformation du binaire
semble bien mince dans l'explication de ce cas !

J'ai l'impression que l'on devrait surtout regarder comment en VBA
on adresse l'espace mémoire aux nombres saisis dans le code...et
leur effet sur le résultat des opérations mathématiques !
Avatar
bcar
Bonjour,

si on fait sous excel( 2000-2002-XP ) (win200, XP)

sub test()
Dim x as Long

x = Int(37.7266 * 10000)
' on obtient x = 377265
' je m'attendais à avoir 377266

' par contre si on fait
x = int(37.7263 * 10000)
' on obtient bien x = 377263
end sub

En fait 37.7263 donne le résultat que j'attends, 37.7264, non, 37.7265,
ok, ....

Avez vous une explication ?


j'ai trouvé quelques explications supplémentaires :

http://tinyurl.com/y4g5qg
http://tinyurl.com/wkmvr

Avatar
MichDenis
Pour ceux que la chose intéresse, je recopie les réponses
que j'ai obtenues du groupe anglais lorsque je leur ai exposé
la problématique de ma réponse précédente :

De Ron Rosenfeld
'---------------------------------
It has to do with the inherent inaccuracies in the IEEE standard for double
precision floating point numbers.

The number 37.7266 cannot be expressed accurately as a binary number. It's
actually the equivalent of something like 37.726599..... so multiplied by 10000
will be 377265.99... and the INT function will return 377265.

However, when you define A as a variant type, I believe the precision
increases, so you wind up with the "correct" answer.

http://www.cpearson.com/excel/rounding.htm discusses rounding errors in Excel.
The concept is equally applicable to VB.
'---------------------------------

En supplément, Ron ajoutait ceci :
'-----------------------------------
Although binary computation should work the same all over, the degree of
precision, and some assumptions made by the programs (Excel vs VBA) are
different.

I have read that Excel makes some assumptions to try to minimize the effects of
binary "inexactness".

In VB, the degree of precision can vary, depending on variable types. An
"undefined" variable type will be defined as a variant, and will retain the
data type of the entered value, unless ... (from HELP):

Generally, numeric Variant data is maintained in its original data type within
the Variant. For example, if you assign an Integer to a Variant, subsequent
operations treat the Variant as an Integer. However, if an arithmetic operation
is performed on a Variant containing a Byte, an Integer, a Long, or a Single,
and the result exceeds the normal range for the original data type, the result
is promoted within the Variant to the next larger data type. A Byte is promoted
to an Integer, an Integer is promoted to a Long, and a Long and a Single are
promoted to a Double. An error occurs when Variant variables containing
Currency, Decimal, and Double values exceed their respective ranges.
'-----------------------------------


Et pour terminer, un spécialiste de la question : Jerry W. Lewis explique :
.'-------------------------------------------..
However, when you define A as a variant type, I believe the precision
increases, so you wind up with the "correct" answer.


Actually, the opposite is true, 4-function arithmetic that involves only
constants and explicitly declared doubles is done in extended precision (10
bytes), where it is only done in double precision (8 bytes) with variants.
It is an accident of this particular calculation that the lower precision
calculation resulting from using variants was more in keeping with the OP's
intent.

It has to do with the inherent inaccuracies in the IEEE standard for double
precision floating point numbers.

The number 37.7266 cannot be expressed accurately as a binary number. It's
actually the equivalent of something like 37.726599..... so multiplied by 10000
will be 377265.99... and the INT function will return 377265.


Exactly right. The IEEE double precision binary representation for 37.7266
has the decimal value of
37.72659999999999769215719425119459629058837890625
When you multiply by 10000, you get
377265.9999999999769215719425119459629058837890625
in extended precision, which is approximated by 377266 in double precision.

Thus
Dim A As Variant, B As Variant
A = 37.7266
B = 10000
X = Int(A * B)
returns 377266 because the Int() function received a double precision value,
whereas the other versions returned 3772655 because the Int() function
received an extended precision value.

There are various ways to insure that Int() receives a double precision
value, including
X = Int(CDbl(A * B))
and
X = A * B
X = Int(X)
but the form least likely to give binary surprises is
X = Int(CDbl(CStr(A * B)))
since it works with no more figures than Excel will display.
'-------------------------------------------


Mes commentaires du message précédent étaient :
'--------------------------------------------
Ceci est aussi possible en utilisant des variables

A = 37.7266
B = 10000
X = Int(A * b)
Résultat obtenu = 377266

Supposons que l'on définisse le type des variables comme suit :
Dim x
Dim A As Double, B As Integer
A = 37.7266
B = 10000
x = Int(A * B)
Résultat obtenu = 377265

Je n'ai pas l'explication...mais le truc de transformation du binaire
semble bien mince dans l'explication de ce cas !

J'ai l'impression que l'on devrait surtout regarder comment en VBA
on adresse l'espace mémoire aux nombres saisis dans le code...et
leur effet sur le résultat des opérations mathématiques !
'--------------------------------------------

Avatar
Patrick Penet
Très intéressant !
Bonne année 2007.
P.