Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Y a comme un défaut

21 réponses
Avatar
josephb
Bonjour,

Sauf erreur de ma part, je viens de faire une découverte déstabilisante.
Des volontaires pour exécuter le petit script que je vous mets en dessous ?
Après le premier test avec la valeur 2.54 pour diviseur
refaites l'essai avec 25.4
Dites-moi si des résultats obtenus chez vous sont conformes ou délirants ?
Je ne me rappelle pas avoir jamais rencontré cette "anomalie" depuis que je tripote appleScript*.
Le bug provient-il de El Cap ou se perpétue-t-il encore ?
* Ce qui ne veut pas dire qu'elle n'était pas déjÍ  lÍ  ?

*******************
set diviseur to 2.54
set serie to {0.254, 2.54, 25.4, 254, 2540}
set restes to {}
set text item delimiters to " - "
set commentaire to "Restes de la division par " & (diviseur as text) & " de" & linefeed & (serie as string)

repeat with value in serie
copy (value mod diviseur) to the end of restes
end repeat
display alert (restes's every item as text) message commentaire

*********************

AppleScript operator Description
mod Remainder.
A binary arithmetic operator that divides the number to its left by the number to its right and returns the remainder as its
result.
Class of operands: integer, real Class of result: integer, real

*********************
pour info, avec 2,54 j'obtiens
0,254 - 0,0 - 2,54 - 2,54 - 2,54

et avec 25,4
0,254 - 2,54 - 0,0 - 1,42108547152E-14 - 1,42108547152E-13

--
J. B.

10 réponses

1 2 3
Avatar
pehache
Le 04/12/2021 Í  12:57, Joseph-B a écrit :
M.V. wrote:
Les grands esprits se rencontrent :
<news:sofc6d$t7u$

Oui, puisque la fonction "Reste de division" est bugguée

Jusqu'Í  preuve du contraire rien n'indique un bug dans ce que tu as
exposé, juste un comportement qu'on peut expliquer en arithmétique
flottante.
Il a été beaucoup reproché Í  Applescript de ne pas obliger Í  déclarer le
type des variables et opérandes utilisés dans le script (Integer, Real,
String, List…), laissant Í  l'interpréteur deviner de quoi il retourne au
prix d'un gÍ¢chis de mémoire et risque d'erreur Í  l'exécution alors que
la compilation n'aura rien détecté d'incohérent.

AS est un langage Í  typage dynamique, c'est loin d'être le seul, et ça a
aussi des avantages, pas uniquement des inconvénients.
Faut-il en rire ?

Surtout pas, c'est désormais interdit, et c'est tant mieux quand on
réalise l'empreinte carbone et la charge virale dangereusement exhalées
Í  chaque éclat de rire.
Sérieusement, ce qu'il nous faut c'est un·e contribut·eur·rice qui
voudra bien lancer un # indigné sur Twitter pour qu'Apple se sorte les
doigts…?

S'il y a un volontaire pour se ridiculiser il peut y aller :-)
--
"...[la moto] un engin qui par les lois de la physique ne peut pas
freiner en courbe.", SLD sur fr.rec.bricolage
"...sois ouvert aux idées des autres pour peu qu'elles aillent dans le
même sens que les tiennes.", ST sur fr.bio.medecine
Avatar
Olivier Miakinen
Le 04/12/2021 13:23, j'écrivais :
Pour info, le nombre 2,54 n'est pas représentable dans un flottant.
Les nombres les plus proches sont :
2 + 1215971899390033/2^51 =~ 2,539999999999999591437926
2 + 1215971899390034/2^51 =~ 2,540000000000000035527136

Pour ceux que ça amuse, une petite calculette IEEE754 :
<http://www.miakinen.net/vrac/ieee754/>
Il n'y a pas de doc, sauf celle intégrée aux scripts en Javascript :
<http://www.miakinen.net/vrac/ieee754/ieee754.js>
<http://www.miakinen.net/vrac/ieee754/ieee754-test.js>
Cela dit, il suffit de savoir que « x » est le nombre IEEE754 Í  manipuler,
et que « n » est un nombre entier qui peut servir Í  des manipulations sur
le nombre « x » en fonction des boutons disponibles.
Les nombres IEEE754 sont bien sÍ»r ceux de Javascript, c'est-Í -dire codés
sur 64 bits (1 bit de signe, 11 bits d'exposant et 52 bits de mantisse).
Sans surprise, le nombre 1215971899390034 est celui qui apparaͮt comme
mantisse (plus exactement comme partie fractionnaire de la mantisse)
quand on donne Í  x la valeur 2.54.
--
Olivier Miakinen
Avatar
M.V.
Le 4 décembre 2021 Í  12 h 57, Joseph-B a tenu les propos suivants :
Les grands esprits se rencontrent :
<news:sofc6d$t7u$

Oui, puisque la fonction "Reste de division" est bugguée et pas la
fonction "partie Entière de division" la ruse est vite trouvée

Essaye en introduisant 25.4001 dans la liste des dividendes avec 2.54
(ou 25.4) comme diviseur :
=+=+=+=+=+=+=+set dividende to 25.4001
set diviseur to 2.54
return Modulo(dividende, diviseur)
on Modulo(dividende, diviseur)
set partieEntiere to (dividende div diviseur)
set reste to (dividende - (partieEntiere * diviseur))
return reste
end Modulo
=+=+=+=+=+=+=+
En passant par des entiers (transformation de 25.4001 en 254001 et
transformation de 2.54 en 254000), on lève ce nouveau souci mais lÍ 
encore, la réponse que j'obtiens, Í  savoir 1,0E-4, ne me plaÍ®t pas du
tout dans sa forme même si elle est plus mieux que le résultat infect
précédent!
Je vois que pour ta routine Modulo(), tu obtiens aussi des résultats du
type 0,0 et, pour moi, ça ne veut pas forcément dire 0 : 0,0 signifie,
pour moi, une valeur approchée au dixième du résultat !!!

Non, par convention dans AppleScript 0 signifie que les calculs et le
résultat ont eté effectués sur des entiers et 0.0 sur des réels

OK. Ma vision d'humain (enfin : de ce qu'il en reste) n'est pas la même
que celle du logiciel ! ;-)
Mais comme ça continuait malgré tout Í  me gêner, j'ai rajouté une ligne
de script pour qu'un entier soit écrit sous forme d'un entier ;-)
--
Michel VAUQUOIS - <http://michelvauquois.fr>
Avatar
M.V.
Le 4 décembre 2021 Í  14 h 01, Fleuger a tenu les propos suivants :
Amusant ! As-tu essayé de reproduire strictement ce que tu me demandes
de faire ?
Ça coince

Oui ! Je me suis demandé pourquoi et j'ai fini par trouver… J'applique
un script avant l'envoi, script qui, entre autres choses, transforme
certaines espaces en espaces insécables : c'est ce qui s'est passé sur
la ligne :
copy (value - (value div diviseur) * diviseur) to the end of restes
Mon script a remplacé les espaces qui encadrent le signe - par des
espaces insécables et AS n'a pas aimé du tout !!!
Ceci dit, sur le mac, j'ai toujours eu des problèmes en essayant de
reproduire dans Excel les calculs des administrations - Impʹts, Caisses
de retraite, banques (bourse).
Pour retrouver les mêmes résultats, il faut que j'introduise Í  tÍ¢tons
dans les formules des ARRONDI, ARRONDI.INF, ARRONDI.SUP en fixant un
nombre de décimales

C'est tout ͠ fait normal ;-)
--
Michel VAUQUOIS - <http://michelvauquois.fr>
Avatar
M.V.
[Supersedes: <sofuv0$lof$]
Le 4 décembre 2021 Í  15 h 25, Joseph-B a tenu les propos suivants :
Pour reprendre l'exemple de MV,
(2.001 -2) avec une calculette Í  moins d'un euro retournera 0,001
Ouais, mais c'est moche et trivial tandis que
(2.001 -2) dans AppleScript retournera 9.9999999999989E-4

En même temps on n'est pas loin de la vérité mathématique car, si tu te
rappelles tes cours de math du siècle dernier :
1 = 0,99999999999999999999999999999999… (ad libitum) ! ;-)
Ceci dit, je partage ton courroux (coucou) surtout quand je vois le
script que j'ai dÍ» pondre pour obtenir un résultat correct (jusqu'Í 
preuve du contraire) pour éviter des résultats Í  la mords-moi le nœud.
J'en suis lÍ  :
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+set diviseur to 25.4
set serie to {0.254, 2.54, 25.4001, 254, 2540}
set restes to {}
set text item delimiters to " - "
set commentaire to "Restes de la division par " & (diviseur as text) & " de" & linefeed & (serie as string)
set exp0 to exp_value(diviseur)
log "exp0 : " & exp0
repeat with value in serie
set exp1 to exp_value(value)
log "exp1 : " & exp1
-- pour transformer 25.4 et 25.4001 par exemple en 254000 et 254001
if exp1 ≥ exp0 then
set exp to exp1
else
set exp to exp0
end if
set new_value to (value * (10 ^ exp)) as integer
set new_diviseur to (diviseur * (10 ^ exp)) as integer
set reste to (new_value mod new_diviseur) / (10 ^ exp)
if reste = (reste as integer) then set reste to reste as integer
copy reste to the end of restes
end repeat
set text item delimiters to " - "
display alert (restes's every item as text) message commentaire
-- combien de chiffres dans la partie décimale
on exp_value(nombre)
set nombre_str to nombre as string
log "nombre_str : " & nombre_str
set text item delimiters to ","
try
set exp to count characters of second text item of nombre_str
on error
set exp to 0
end try
return exp
end exp_value
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+--
Michel VAUQUOIS - <http://michelvauquois.fr>
Avatar
pehache
Le 04/12/2021 Í  15:25, Joseph-B a écrit :
pehache wrote:
Le truc classique c'est (1+1e-16)-1 dont le résultat est zéro
exactement, parce que la représentation d'un flottant 64 bits ne peut
pas différencier (1+1e-16) de 1

Je me moque éperdument que les limites du calcul en virgule flottante Í 
e-14 ou e-16 les confondent Í  zéro,

Si tu n'essayes pas de comprendre ça, la discussion ne peut en effet pas
aller bien loin.
ce que vous n'avez pas l'air de
comprendre c'est qu'il n'est pas admissible de la part d'ingénieurs de
laisser faire en sorte que leur bijou d'intelligence et de science ne
soit pas cohérent avec la réalité triviale.

Les bijoux en question sont tout Í  fait cohérents avec la "réalité
triviale" Í  condition d'être utilisés avec discernement. En l'occurrence
ce que tu considères comme étant ta "réalité triviale" est plus du
ressort des calculs sur des nombres entiers ou en virgule fixe qu'en
virgule flottante. A chaque problème le bon outil, on peut arriver Í 
planter un clou avec un tournevis mais ce n'est pas top.
Je te signale qu'Í  ma connaissance tout ce qui est informatique
financière/comptable n'utilise pas les calculs en virgule flottante mais
en virgule fixe, justement pour ne pas tomber dans les problèmes
d'arrondis inhérents Í  la représentation en virgule flottante. Certains
langage ont des types en virgule fixe (typiquement le COBOL), et
certains systèmes informatiques avaient même le support de la virgule
fixe en hardware.
Pour reprendre l'exemple de MV,
(2.001 -2) avec une calculette Í  moins d'un euro retournera 0,001
Ouais, mais c'est moche et trivial tandis que
(2.001 -2) dans AppleScript retournera 9.9999999999989E-4

Historiquement, les calculettes basiques travaillaient en virgule fixe,
justement. En virgule fixe, 2.001 ou 2.54 ont une représentation exacte.
Après, même quand un système/langage travaille en virgule flottante il
ne faut pas confondre ce qu'il affiche et ce qu'il représente en
interne. Par exemple dans Octave (Matlab-like) :
(2.001-2)


ans = 1.0000e-03
(2.001-2)*1e18


ans = 1.0000e+15
int64((2.001-2)*1e18)


ans = 999999999999890
Il peut y avoir une mise en forme du résultat pour que ceux qui seraient
choqués par le résultat informatique ne crient pas au scandale :)
et ça c'est dÍ» Í  une science tellement supérieure qu'elle devrait clore
le bec des ignorants même si c'est en contradiction avec l'enseignement
de l'arithmétique élémentaire.

Le truc c'est *jamais* personne n'a prétendu que l'arithmétique en
virgule flottante était de l'arithmétique exacte. Dans l'enseignement du
calcul numérique sur ordinateur c'est une des premières choses qu'on
apprend (ou qu'on devrait apprendre) : en virgule flottante on fait des
calculs FAUX. Tout l'enjeu est alors de maͮtriser les pertes de
précision au cours des calcul (car les erreurs d'arrondis ont la
désagréable propriété de se cumuler et même parfois d'exploser), et de
savoir écrire du code de façon Í  les minimiser.
Mac, PC, Supercalculateur ou calculette Í  2 balles, ne sont que des put…
d'outils./
Il n'est pas acceptable que ce soit Í  l'utilisateur lambda dans le cadre
de son utilisation basique (2.001 -2 sur un Mac) de ne s'en prendre qu'Í 
lui même parce qu'il a eu l'impudence de soumettre un calcul dont le
résultat affiché (pour "légitime" qu'il soit) est en contradiction avec
ce que ces pauvres ignorantins de maÍ®tres d'école ont passé des vies Í 
enseigner.

"A chaque problème le bon outil". Si tu plante ton clou avec un
tournevis ce n'est pas au fabricant du tournevis qu'il faut t'en prendre
si ça ne va pas.
D'après toi et OM ce serait au clampin utilisateur d'établir des
procédures de tests de validité des librairies mathématiques que les
ingénieurs d'Apple n'ont pas prix la peine de faire ?

Non mais déconner tu penses vraiment que les ingénieurs d'Apple sont
idiots Í  ce point ?
--
"...[la moto] un engin qui par les lois de la physique ne peut pas
freiner en courbe.", SLD sur fr.rec.bricolage
"...sois ouvert aux idées des autres pour peu qu'elles aillent dans le
même sens que les tiennes.", ST sur fr.bio.medecine
Avatar
josephb
pehache wrote:
"A chaque problème le bon outil". Si tu plante ton clou avec un
tournevis ce n'est pas au fabricant du tournevis qu'il faut t'en prendre
si ça ne va pas.

Aussi longtemps qu'Applescript ne laissera pas le choix de travailler en
floatting-point ou fixed-point, obligeant Í  des contorsions insensées
pour s'assurer qu'une opération aussi banale que 2.001-2 = 0.001 est
réalisée,
ou pour ne pas se retrouver avec le reste égal au diviseur dans une
fonction de division native de l'OS,
j'estimerai Í  bon droit que l'outil est partiellement défaillant et que
la responsabilité ne m'en incombe pas.
--
J. B.
Avatar
josephb
M.V. wrote:
Ceci dit, je partage ton courroux (coucou) surtout quand je vois le
script que j'ai dÍ» pondre pour obtenir un résultat correct (jusqu'Í 
preuve du contraire) pour éviter des résultats Í  la mords-moi le nœud.
J'en suis lÍ  :

Snip du script qui fonctionne… jusqu'Í  un certain point :
set serie to {0.254, 2.54, 25.4001, 254, 2540}
Tu auras beau rentrer la valeur en integer, Í  partir d'un moment
AppleScript va décider de passer en notation exponentielle et ça va
capoter.
Mets 254000000 en dernier et regarde ce qu'il se passe.
Pire si tu mets directement 2.54E+4 au lieu de 25400.
Je n'ai pas cherché Í  savoir si ça vient de ta procédure, mais c'est
probablement encore une histoire de tournevis Vs marteau, donc c'est ta
faute ;-)
--
J. B.
Avatar
JPP
On 04/12/21 15:21, Joseph-B wrote:
Aussi longtemps qu'Applescript ne laissera pas le choix de travailler en
floatting-point ou fixed-point, obligeant Í  des contorsions insensées
pour s'assurer qu'une opération aussi banale que 2.001-2 = 0.001 est
réalisée,

La Calculette de HSierra donne bien 2.001-2 = 0.001
Idem pour PCalc et même Excel :-)
(Ma) conclusion : le problème évoqué par JB est bien du cÍ´té d'AppleScript.
Avatar
Julien Salort
Le 04/12/2021 Í  10:14, Joseph-B a écrit :
Il n'y a pas forcément de défaut, calculer des restes en arithmétique
flottante est forcément casse-gueule quand le résultat de la division
est censé être une valeur entière. Quand tu écris "2,54" (ou n'importe
quelle autre valeur) la représentation en machine est une approximation
de cette valeur, ce n'est pas la valeur exacte (sauf coup de chance).

Ton argument serait recevable, encore que très dérangeant dans les
calculs pratiques, pour (254 mod 25.4) ==> 1.4210854715202E-14
L͠ o͹ il n'est plus soutenable c'est pour (254 mod 2.54) ==> 2.54

C'est un problème de IEEE-754.
On le voit par exemple en Python, si on compare le résultat entre le
calcul avec des flottants natifs, ou avec des décimaux:
% python
Python 3.10.0 (default, Nov 12 2021, 18:16:44) [Clang 13.0.0
(clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
254 % 2.54



2.5399999999999965
from decimal import Decimal
Decimal("254") % Decimal("2.54")



Decimal('0.00')
Bien sÍ»r, les décimaux peuvent avoir le même genre de problèmes. Mais la
différence c'est que les nombres qui s'écrivent exactement en décimal
seront représentés exactement. Pour les flottants, il faut que la
représentation en base 2 soit exacte.
1 2 3