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

Le type q inclu dans Leopard?

19 réponses
Avatar
Archidemon
Bonjour!

Est-ce que le le perl qui vient avec Leopard supporte le type Q
(quadratic float)?

Voici ce que j'ai fait rouler:


#!/bin/bash
rqs () {
perl -e '
$sign = 0;
if (($numerator = $ARGV[0]) < 0) {
$numerator = -$numerator;
$sign = 1;
}
if (($denominator = $ARGV[1]) < 0) {
$denominator = -$denominator;
$sign = 1-$sign;
}
$quotient = $numerator / $denominator;
$bs = pack "d",$quotient;
$qi = unpack "Q",$bs;
$bs = pack "Q",++$qi;
$successor = unpack "d",$bs;
$bs = pack "d",$quotient;
$qi = unpack "Q",$bs;
$bs = pack "Q",--$qi;
$predecessor = unpack "d",$bs;
for ($precision = 1;;++$precision) {
$qs = sprintf "%.${precision}f",$quotient;
$ss = sprintf "%.${precision}f",$successor;
last if $qs ne $ss;
}
for (;;++$precision) {
$qs = sprintf "%.${precision}f",$quotient;
$ps = sprintf "%.${precision}f",$predecessor;
last if $qs ne $ps;
}
$quotient = -$quotient if $sign;
printf "%.${precision}f",$quotient;
' $1 $2



}


foo="$(rqs 512 918)"

****
Voici ce que j'ai obtenu:
****
Invalid type 'Q' in unpack at -e line 13.

9 réponses

1 2
Avatar
Paul Gaborit
À (at) Sun, 5 Jul 2009 04:38:37 -0700 (PDT),
KingKong écrivait (wrote):
snip
Quel est le problème avec ce programme ? Qu'est-il censé faire ?


snip

La fonction calcule un quotient comme java le fait. Il va falloir que
j'utilise une version en 32 bits.



Ça ne m'éclaire en rien sur le résultat attendu !

Par ailleurs pour que ça marche j'ai découvert qu'il faut alors
traiter le tout en little endian sur Mac.



Si votre programme dépend de cela, c'est qu'il est mal conçu. Ce n'est
pas le Mac qui est en little ou en big endian. C'est le processeur du
Mac que vous utilisez.

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
KingKong
snip
>> Quel est le problème avec ce programme ? Qu'est-il censé faire ?
>  snip

> La fonction calcule un quotient comme java le fait. Il va falloir que
> j'utilise une version en 32 bits.

Ça ne m'éclaire en rien sur le résultat attendu !




Ce que je veux, et je le fait maintenant, c'est précisément de
calculer un quotient exactement comme Java le fait.

Par exemple, je veux que 512/918 donne exactement 0.5577342047930284.
Avec BC, scale 16, on obtient: .5577342047930283.
Avec BC, scale 17, on obtient .55773420479302832.


> Par ailleurs pour que ça marche j'ai découvert qu'il faut alors
> traiter le tout en little endian sur Mac.

Si votre programme dépend de cela, c'est qu'il est mal conçu.



Il faudrait probablement tester l'endianness du processeur. C'est une
objection valide et si je décide de développer pour plus d'une
machine, je vais m'en souvenir.

Ce n'est
pas le Mac qui est en little ou en big endian. C'est le processeur du
Mac que vous utilisez.



C'est un point que je vais garder à l'esprit. Merci!
Avatar
Eric Levenez
Le 05/07/09 19:40, dans
,
« KingKong » a écrit :

Ce que je veux, et je le fait maintenant, c'est précisément de
calculer un quotient exactement comme Java le fait.

Par exemple, je veux que 512/918 donne exactement 0.5577342047930284.
Avec BC, scale 16, on obtient: .5577342047930283.
Avec BC, scale 17, on obtient .55773420479302832.



Donc, si je comprends bien, ton problème n'est pas sur un calcul entier,
mais sur un calcul flottant. Le code suivant affiche bien le résultat que tu
attends : 0.5577342047930284

my $a = 512.0;
my $b = 918.0;
my $c = $a / $b;

printf "%.16fn", $c;

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.
Avatar
Paul Gaborit
À (at) Sun, 5 Jul 2009 10:40:17 -0700 (PDT),
KingKong écrivait (wrote):
snip
>> Quel est le problème avec ce programme ? Qu'est-il censé faire ?
>  snip

> La fonction calcule un quotient comme java le fait. Il va falloir que
> j'utilise une version en 32 bits.

Ça ne m'éclaire en rien sur le résultat attendu !




Ce que je veux, et je le fait maintenant, c'est précisément de
calculer un quotient exactement comme Java le fait.

Par exemple, je veux que 512/918 donne exactement 0.5577342047930284.
Avec BC, scale 16, on obtient: .5577342047930283.
Avec BC, scale 17, on obtient .55773420479302832.



La commande suivante :

% perl -e 'printf "%.16fn", shift()/shift()' 512 918

semble afficher le résultat que vous souhaitez.

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
KingKong
snip

Donc, si je comprends bien, ton problème n'est pas sur un calcul entier ,
mais sur un calcul flottant. Le code suivant affiche bien le résultat q ue tu
attends : 0.5577342047930284

my $a = 512.0;
my $b = 918.0;
my $c = $a / $b;

printf "%.16fn", $c;



Merci beaucoup mais le processus de Java est exactement celui que j'ai
maintenant trouvé. Il n'est pas nécessairement sur 16 décimales. La
dernière décimale est celle pour laquelle survient une différence
entre le quotient "intacte" et soit la représentation en binaire du
quotient plus 1 ou soit soit la représentation en binaire du quotient
moins 1.

voici d'autres exemples:

256/626
0.40894568690095845

512/918
0.5577342047930284

256/2504
0.10223642172523961

256/3672
0.06971677559912855

Ces quotients peuvent avoir 17 décimales ou 16 décimales ou peut-être
moins encore.
Avatar
KingKong
snip

> Par exemple, je veux que 512/918 donne exactement 0.5577342047930284.
> Avec BC, scale 16, on obtient: .5577342047930283.
> Avec BC, scale 17, on obtient .55773420479302832.

La commande suivante :

   % perl -e 'printf "%.16fn", shift()/shift()' 512 918

semble afficher le résultat que vous souhaitez.



Merci!

Le processus pour simuler Java, que j'ai trouvé, peut exiger un nombre
variable de décimales. Le code que j'ai donné s'explique par des
comparaisons sur le quotient avec les décimales du nombre dont la
représentation binaire précède le quotient et avec les décimales du
nombre dont la représentation binaire suit le quotient.

Si vous avez un perl à 64 bits, essayer et vous verrez. Je l'ai porté
sur 32 bits et ça fonctionne aussi.
Avatar
Paul Gaborit
À (at) Sun, 5 Jul 2009 15:08:07 -0700 (PDT),
KingKong écrivait (wrote):
Le processus pour simuler Java, que j'ai trouvé, peut exiger un nombre
variable de décimales. Le code que j'ai donné s'explique par des
comparaisons sur le quotient avec les décimales du nombre dont la
représentation binaire précède le quotient et avec les décimales du
nombre dont la représentation binaire suit le quotient.



J'ai du mal à croire que Java fasse toute cette cuisine et surtout de
cette manière... Êtes-vous sûr qu'une nouvelle version de Java ou de
la machine virtuelle ne va pas changer cela ? Ou, au moins, êtes-vous
sûr qu'il n'y a pas quelque part une description formelle (autre que
du code) de ce calcul ? La solution la plus simple ne serait-elle pas
de coder directement en Java ?

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
KingKong
snip

J'ai du mal à croire que Java fasse toute cette cuisine et surtout de
cette manière... Êtes-vous sûr qu'une nouvelle version de Java ou d e
la machine virtuelle ne va pas changer cela ?



Peut-être mais ça n'a pas d'importance car ça va me permettre de
traiter des données qui existent déjà. Je suis en train de voir
comment mettre à jour tout cela en creusant d'un côté plus
fondamental. Ce n'est pas ma préoccupation pour l'instant.

Ou, au moins, êtes-vous
sûr qu'il n'y a pas quelque part une description formelle (autre que
du code) de ce calcul ?



Je la cherche et je vous en ferai part.


La solution la plus simple ne serait-elle pas
de coder directement en Java ?



Pour des raisons d'intégration de plusieurs outils je préfère
travailler en perl.
Avatar
Eric Levenez
Le 05/07/09 23:57, dans
,
« KingKong » a écrit :

snip

Donc, si je comprends bien, ton problème n'est pas sur un calcul entier,
mais sur un calcul flottant. Le code suivant affiche bien le résultat que tu
attends : 0.5577342047930284

my $a = 512.0;
my $b = 918.0;
my $c = $a / $b;

printf "%.16fn", $c;



Merci beaucoup mais le processus de Java est exactement celui que j'ai
maintenant trouvé. Il n'est pas nécessairement sur 16 décimales. La
dernière décimale est celle pour laquelle survient une différence
entre le quotient "intacte" et soit la représentation en binaire du
quotient plus 1 ou soit soit la représentation en binaire du quotient
moins 1.

voici d'autres exemples:

256/626
0.40894568690095845

512/918
0.5577342047930284

256/2504
0.10223642172523961

256/3672
0.06971677559912855

Ces quotients peuvent avoir 17 décimales ou 16 décimales ou peut-être
moins encore.



J'ai comme l'impression qu'il y a comme un loup là dessous. Les flottants
sont codés en binaires, et la précision (sur 64 bits) n'est garantie que
jusqu'à 15 chiffres par la norme IEEE 754, bien que l'on utilise couramment
16 voir 17 chiffres. Et souvent la différence sur le dernier chiffre dépend
totalement de la fonction print du langage et pas du calcul effectué en
lui-même qui lui dépend du CPU utilisé et de la façon dont il interprète la
norme IEEE. Il y a des threads entiers sur les problèmes de calcul en
flottant sur les CPU et en particulier avec les optimisations effectués sur
les CPU qui utilisent parfois plus de 64 bits pour les calculs
intermédiaires.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.
1 2