kanze wrote:Mais ce n'était qu'une remarque parenthètique, parce que ça ne change
rien au problème. Grosso modo, si je comprends ce que tu veux dire,
c'est que si j'ajoute deux nombres de 6 chiffres, il faut que
j'utilise l'arithmétique à 12 chiffres, et que je garde le résultat
sur 12 chiffres (minimum, évidemment). Que la précision nécessaire
est la somme des précisions en entrée.
Là, je ne suis plus certain de suivre. La précision d'un flottant,
c'est la précision de sa mantisse, il me semble (qui correspond au
nombre de chiffres significatifs). Mais si l'on additionne deux
flottants avec un même nombre de chiffres significatifs, mais des
exposants très éloignés, on fait bien plus que doubler le nombre de
chiffres significatifs nécessaires pour conserver la précision voulue.
Du coup, je ne comprends pas pourquoi il faudrait particulièrement 12
chiffres significatifs pour additionner deux nombres ayant 6 chiffres
significatifs.
kanze wrote:
Mais ce n'était qu'une remarque parenthètique, parce que ça ne change
rien au problème. Grosso modo, si je comprends ce que tu veux dire,
c'est que si j'ajoute deux nombres de 6 chiffres, il faut que
j'utilise l'arithmétique à 12 chiffres, et que je garde le résultat
sur 12 chiffres (minimum, évidemment). Que la précision nécessaire
est la somme des précisions en entrée.
Là, je ne suis plus certain de suivre. La précision d'un flottant,
c'est la précision de sa mantisse, il me semble (qui correspond au
nombre de chiffres significatifs). Mais si l'on additionne deux
flottants avec un même nombre de chiffres significatifs, mais des
exposants très éloignés, on fait bien plus que doubler le nombre de
chiffres significatifs nécessaires pour conserver la précision voulue.
Du coup, je ne comprends pas pourquoi il faudrait particulièrement 12
chiffres significatifs pour additionner deux nombres ayant 6 chiffres
significatifs.
kanze wrote:Mais ce n'était qu'une remarque parenthètique, parce que ça ne change
rien au problème. Grosso modo, si je comprends ce que tu veux dire,
c'est que si j'ajoute deux nombres de 6 chiffres, il faut que
j'utilise l'arithmétique à 12 chiffres, et que je garde le résultat
sur 12 chiffres (minimum, évidemment). Que la précision nécessaire
est la somme des précisions en entrée.
Là, je ne suis plus certain de suivre. La précision d'un flottant,
c'est la précision de sa mantisse, il me semble (qui correspond au
nombre de chiffres significatifs). Mais si l'on additionne deux
flottants avec un même nombre de chiffres significatifs, mais des
exposants très éloignés, on fait bien plus que doubler le nombre de
chiffres significatifs nécessaires pour conserver la précision voulue.
Du coup, je ne comprends pas pourquoi il faudrait particulièrement 12
chiffres significatifs pour additionner deux nombres ayant 6 chiffres
significatifs.
Du coup, je ne comprends pas pourquoi il faudrait particulièrement 12
chiffres significatifs pour additionner deux nombres ayant 6 chiffres
significatifs.
Moi non plus, mais c'est ce qu'il a dit. (À mon avis, si j'ajoute 10^-20
à 10^20, même si les deux n'ont que 6 chiffres de précision, il me faut
bien 40 chiffres au moins pour ne pas avoir une perte de précision.)
Du coup, je ne comprends pas pourquoi il faudrait particulièrement 12
chiffres significatifs pour additionner deux nombres ayant 6 chiffres
significatifs.
Moi non plus, mais c'est ce qu'il a dit. (À mon avis, si j'ajoute 10^-20
à 10^20, même si les deux n'ont que 6 chiffres de précision, il me faut
bien 40 chiffres au moins pour ne pas avoir une perte de précision.)
Du coup, je ne comprends pas pourquoi il faudrait particulièrement 12
chiffres significatifs pour additionner deux nombres ayant 6 chiffres
significatifs.
Moi non plus, mais c'est ce qu'il a dit. (À mon avis, si j'ajoute 10^-20
à 10^20, même si les deux n'ont que 6 chiffres de précision, il me faut
bien 40 chiffres au moins pour ne pas avoir une perte de précision.)
C'est moins le problème d'identité dans le code (utiliser = > après deux calculs identiques) que celui de garantir la même sortie
entre deux exécutables compilés à partir du même code source,
sachant qu'une faible différence dans le résultat d'un calcul peut
entraîner de grosses différences dans ladite sortie.
C'est moins le problème d'identité dans le code (utiliser = > après deux calculs identiques) que celui de garantir la même sortie
entre deux exécutables compilés à partir du même code source,
sachant qu'une faible différence dans le résultat d'un calcul peut
entraîner de grosses différences dans ladite sortie.
C'est moins le problème d'identité dans le code (utiliser = > après deux calculs identiques) que celui de garantir la même sortie
entre deux exécutables compilés à partir du même code source,
sachant qu'une faible différence dans le résultat d'un calcul peut
entraîner de grosses différences dans ladite sortie.
pour des calculs trigonométriques et/ou log/exp, cela sera
plus difficile car ces fonctions sont tabulées et tous les
chips ne contiennent pas les mêmes tables; ici la
précision rendue devra être plus limitée.
pour des calculs trigonométriques et/ou log/exp, cela sera
plus difficile car ces fonctions sont tabulées et tous les
chips ne contiennent pas les mêmes tables; ici la
précision rendue devra être plus limitée.
pour des calculs trigonométriques et/ou log/exp, cela sera
plus difficile car ces fonctions sont tabulées et tous les
chips ne contiennent pas les mêmes tables; ici la
précision rendue devra être plus limitée.
Jean-Marc Bourguet wrote on 17/05/2006 15:19:Sylvain writes:tes routines sont intéressantes ! de mon point de vue, elles sont toutes
inadaptées et maladroites (ce n'est pas une provocation!).
En quoi sont-elles inadaptees a l'objectif poursuivi: analyser
l'erreur introduite par differentes manieres de faire la somme
(definie comme etant la difference entre le resultat exact arrondi a
la precision d'un float et le resultat calculer)?
pour cet objectif, elles sont très bien... si utilisées correctement [1]
je me plaçais dans un cadre de traitement numérique et commentais le main()
de James qui ne contient que des SumXXX<float>; là je maintiens que un
SumUp<double> est suffisant.
dans tes benchs tu accumules 1.000.000 de valeurs
flottantes de type float, or un float à une précision
de 10^-6, en sommer 10^6 va obligeatoirement faire
perdre toute précision de l'élément ajouté par rapport
à l'accu courant - ie va générer un débordement de
précision et revient à faire un inf + epsilon en
espérant trouver l'epsilon dans le nouveau résultat.
Je ne comprends pas.
tu ne comprends pas quoi ?
que le nombre de chiffres significatifs est limité ? que
(float)(500000. + 0.512345) vaut 500000. et non
500000.512345 ?
Dans le cadre donne ci-dessus, on peut prouver des
bornes superieures pour l'erreur introduite pour deux
des algorithmes (sumPriority, sumCompensated) qui sont
de l'ordre de quelques ULP (si j'ai bonne memoire, moins
d'un ULP pour sumCompensated, autrement dit, une des
valeurs qui encadrent le resultat exact).
le problème est que pour la valeur 0.512345 lorsqu'elle
est ajouté à 500000. c'est même son UFP qui se volatilise
Jean-Marc Bourguet wrote on 17/05/2006 15:19:
Sylvain <noSpam@mail.net> writes:
tes routines sont intéressantes ! de mon point de vue, elles sont toutes
inadaptées et maladroites (ce n'est pas une provocation!).
En quoi sont-elles inadaptees a l'objectif poursuivi: analyser
l'erreur introduite par differentes manieres de faire la somme
(definie comme etant la difference entre le resultat exact arrondi a
la precision d'un float et le resultat calculer)?
pour cet objectif, elles sont très bien... si utilisées correctement [1]
je me plaçais dans un cadre de traitement numérique et commentais le main()
de James qui ne contient que des SumXXX<float>; là je maintiens que un
SumUp<double> est suffisant.
dans tes benchs tu accumules 1.000.000 de valeurs
flottantes de type float, or un float à une précision
de 10^-6, en sommer 10^6 va obligeatoirement faire
perdre toute précision de l'élément ajouté par rapport
à l'accu courant - ie va générer un débordement de
précision et revient à faire un inf + epsilon en
espérant trouver l'epsilon dans le nouveau résultat.
Je ne comprends pas.
tu ne comprends pas quoi ?
que le nombre de chiffres significatifs est limité ? que
(float)(500000. + 0.512345) vaut 500000. et non
500000.512345 ?
Dans le cadre donne ci-dessus, on peut prouver des
bornes superieures pour l'erreur introduite pour deux
des algorithmes (sumPriority, sumCompensated) qui sont
de l'ordre de quelques ULP (si j'ai bonne memoire, moins
d'un ULP pour sumCompensated, autrement dit, une des
valeurs qui encadrent le resultat exact).
le problème est que pour la valeur 0.512345 lorsqu'elle
est ajouté à 500000. c'est même son UFP qui se volatilise
Jean-Marc Bourguet wrote on 17/05/2006 15:19:Sylvain writes:tes routines sont intéressantes ! de mon point de vue, elles sont toutes
inadaptées et maladroites (ce n'est pas une provocation!).
En quoi sont-elles inadaptees a l'objectif poursuivi: analyser
l'erreur introduite par differentes manieres de faire la somme
(definie comme etant la difference entre le resultat exact arrondi a
la precision d'un float et le resultat calculer)?
pour cet objectif, elles sont très bien... si utilisées correctement [1]
je me plaçais dans un cadre de traitement numérique et commentais le main()
de James qui ne contient que des SumXXX<float>; là je maintiens que un
SumUp<double> est suffisant.
dans tes benchs tu accumules 1.000.000 de valeurs
flottantes de type float, or un float à une précision
de 10^-6, en sommer 10^6 va obligeatoirement faire
perdre toute précision de l'élément ajouté par rapport
à l'accu courant - ie va générer un débordement de
précision et revient à faire un inf + epsilon en
espérant trouver l'epsilon dans le nouveau résultat.
Je ne comprends pas.
tu ne comprends pas quoi ?
que le nombre de chiffres significatifs est limité ? que
(float)(500000. + 0.512345) vaut 500000. et non
500000.512345 ?
Dans le cadre donne ci-dessus, on peut prouver des
bornes superieures pour l'erreur introduite pour deux
des algorithmes (sumPriority, sumCompensated) qui sont
de l'ordre de quelques ULP (si j'ai bonne memoire, moins
d'un ULP pour sumCompensated, autrement dit, une des
valeurs qui encadrent le resultat exact).
le problème est que pour la valeur 0.512345 lorsqu'elle
est ajouté à 500000. c'est même son UFP qui se volatilise
Mais à ma connaissance, les tables ne sont pas la manière
préférée d'implémenter ces fonctions.
Deux techniques sont couremment utilisées, CORDIC
(http://orochoir.club.fr/Maths/cordic.htm) et la réduction
dans un intervalle par des propriétés mathématiques suivie
de l'utilisation d'un polynome d'approximation.
Mais à ma connaissance, les tables ne sont pas la manière
préférée d'implémenter ces fonctions.
Deux techniques sont couremment utilisées, CORDIC
(http://orochoir.club.fr/Maths/cordic.htm) et la réduction
dans un intervalle par des propriétés mathématiques suivie
de l'utilisation d'un polynome d'approximation.
Mais à ma connaissance, les tables ne sont pas la manière
préférée d'implémenter ces fonctions.
Deux techniques sont couremment utilisées, CORDIC
(http://orochoir.club.fr/Maths/cordic.htm) et la réduction
dans un intervalle par des propriétés mathématiques suivie
de l'utilisation d'un polynome d'approximation.
Jean-Marc Bourguet wrote on 20/05/2006 21:30:Mais à ma connaissance, les tables ne sont pas la manière
préférée d'implémenter ces fonctions.
pour du hard (surtout les "petits" CPU) c'est la manière
préférée;
mais concernant, par exemple, un Itanium avec toute sa
quincaillerie, je n'ai aucune info précise sur sa façon de
faire.
Deux techniques sont couremment utilisées, CORDIC
(http://orochoir.club.fr/Maths/cordic.htm) et la réduction
dans un intervalle par des propriétés mathématiques suivie
de l'utilisation d'un polynome d'approximation.
les développements de Cordic
et suite de Taylor sont les plus courantes, le
developpement par produit d'Euler existe aussi mais il
converge moins bien et est au final trop couteux.
Jean-Marc Bourguet wrote on 20/05/2006 21:30:
Mais à ma connaissance, les tables ne sont pas la manière
préférée d'implémenter ces fonctions.
pour du hard (surtout les "petits" CPU) c'est la manière
préférée;
mais concernant, par exemple, un Itanium avec toute sa
quincaillerie, je n'ai aucune info précise sur sa façon de
faire.
Deux techniques sont couremment utilisées, CORDIC
(http://orochoir.club.fr/Maths/cordic.htm) et la réduction
dans un intervalle par des propriétés mathématiques suivie
de l'utilisation d'un polynome d'approximation.
les développements de Cordic
et suite de Taylor sont les plus courantes, le
developpement par produit d'Euler existe aussi mais il
converge moins bien et est au final trop couteux.
Jean-Marc Bourguet wrote on 20/05/2006 21:30:Mais à ma connaissance, les tables ne sont pas la manière
préférée d'implémenter ces fonctions.
pour du hard (surtout les "petits" CPU) c'est la manière
préférée;
mais concernant, par exemple, un Itanium avec toute sa
quincaillerie, je n'ai aucune info précise sur sa façon de
faire.
Deux techniques sont couremment utilisées, CORDIC
(http://orochoir.club.fr/Maths/cordic.htm) et la réduction
dans un intervalle par des propriétés mathématiques suivie
de l'utilisation d'un polynome d'approximation.
les développements de Cordic
et suite de Taylor sont les plus courantes, le
developpement par produit d'Euler existe aussi mais il
converge moins bien et est au final trop couteux.
Dans le cadre donne ci-dessus, on peut prouver des
bornes superieures pour l'erreur introduite pour deux
des algorithmes (sumPriority, sumCompensated) qui sont
de l'ordre de quelques ULP (si j'ai bonne memoire, moins
d'un ULP pour sumCompensated, autrement dit, une des
valeurs qui encadrent le resultat exact).
Note si on veut me citer, la borne dépend du nombre
d'éléments sommés. Et pour ceux qui ne l'aurait pas
remarque, sumCompensated est un moyen de doubler la
précision (donc sumCompensated<float> est légèrement moins
bon que sumCompensated<double> parce qu'il a 48 bits de
précision tandis que les doubles en ont 53, le nombre de
bits affectés à l'exposant ne doublant pas et le signe
n'étant naturellement pas doublé).
Dans le cadre donne ci-dessus, on peut prouver des
bornes superieures pour l'erreur introduite pour deux
des algorithmes (sumPriority, sumCompensated) qui sont
de l'ordre de quelques ULP (si j'ai bonne memoire, moins
d'un ULP pour sumCompensated, autrement dit, une des
valeurs qui encadrent le resultat exact).
Note si on veut me citer, la borne dépend du nombre
d'éléments sommés. Et pour ceux qui ne l'aurait pas
remarque, sumCompensated est un moyen de doubler la
précision (donc sumCompensated<float> est légèrement moins
bon que sumCompensated<double> parce qu'il a 48 bits de
précision tandis que les doubles en ont 53, le nombre de
bits affectés à l'exposant ne doublant pas et le signe
n'étant naturellement pas doublé).
Dans le cadre donne ci-dessus, on peut prouver des
bornes superieures pour l'erreur introduite pour deux
des algorithmes (sumPriority, sumCompensated) qui sont
de l'ordre de quelques ULP (si j'ai bonne memoire, moins
d'un ULP pour sumCompensated, autrement dit, une des
valeurs qui encadrent le resultat exact).
Note si on veut me citer, la borne dépend du nombre
d'éléments sommés. Et pour ceux qui ne l'aurait pas
remarque, sumCompensated est un moyen de doubler la
précision (donc sumCompensated<float> est légèrement moins
bon que sumCompensated<double> parce qu'il a 48 bits de
précision tandis que les doubles en ont 53, le nombre de
bits affectés à l'exposant ne doublant pas et le signe
n'étant naturellement pas doublé).
mais concernant, par exemple, un Itanium avec toute sa
quincaillerie, je n'ai aucune info précise sur sa façon de
faire.
Je n'ai jamais vu d'info publiée la-dessus, mais je n'ai pas
réellement cherché.
mais concernant, par exemple, un Itanium avec toute sa
quincaillerie, je n'ai aucune info précise sur sa façon de
faire.
Je n'ai jamais vu d'info publiée la-dessus, mais je n'ai pas
réellement cherché.
mais concernant, par exemple, un Itanium avec toute sa
quincaillerie, je n'ai aucune info précise sur sa façon de
faire.
Je n'ai jamais vu d'info publiée la-dessus, mais je n'ai pas
réellement cherché.
Pour le moment, je n'ai que les x86 et les ia64 qui ont des fonctions
trigonometriques cablees.
Pour le moment, je n'ai que les x86 et les ia64 qui ont des fonctions
trigonometriques cablees.
Pour le moment, je n'ai que les x86 et les ia64 qui ont des fonctions
trigonometriques cablees.