6
votes

Racine de cube fiable à Haskell

Je vais Question 62 au projet Euler et est venu avec le Suivant pour tester si un numéro est cubique: xxx pré>

mais en raison d'une erreur de point flottant, il renvoie des résultats incorrects: P>

No instances for (Floating Integer, RealFrac Integer)
   arising from a use of `isCube' at prob62.hs:10:44-49


0 commentaires

4 Réponses :


3
votes

Je ne sais pas grand chose à propos de Haskell, mais je prendrais la racine du cube, arrondi au détail entier, prenez le cube et comparez à la valeur d'origine.


0 commentaires

8
votes

Essayez d'éviter d'utiliser autant que possible les numéros de virgule flottante, en particulier lorsque vous avez un problème qui concerne les valeurs entières. Les numéros de points flottants ont des problèmes d'arrondissement et que certaines valeurs (comme 1/3) ne peuvent pas être représentées exactement. Il n'est donc pas surprenant que vous obtenez des réponses mystérieuses.

Tout d'abord, afin de corriger votre erreur, vous devez redéfinir iscube code>. Si vous vérifiez que la signature de type, il ressemble à ceci: p> xxx pré>

Notez qu'il attend quelque chose de classe flottant code> comme premier argument. Votre problème est que vous souhaitez utiliser cette fonction sur les valeurs entières et les entiers ne sont pas une instance de flottant code>. Vous pouvez redéfinir iscube code> comme ceci pour créer le type de fonction Vérifier. P>

isCube x = (round (fromIntegral x ** (1/3))) ^ 3 == x


0 commentaires

0
votes

perms code> a le type [entier] code>. ISCUBE CODE> a le type (RealFrac A, flottant A) => A -> bool code> (comme vous pouvez vérifier dans ghci). La contrainte realfrac code> provient de x x code>, la contrainte flottant code> provient de x ** (1/3) code>. Etant donné que entier code> n'est ni realfrac code> ni flottant code>, iscre code> ne peut pas em> être utilisé comme Integer -> Bool Code>. Donc, filtre iSCube (Perms n) code> n'a pas de sens.

Vous devez donc corriger iscube code> pour fonctionner correctement sur entier code> S: P>

isCube x = isInt $ (fromInteger x)**(1/3)


0 commentaires

1
votes

Pour une autre approche utile pour Entier code> Les valeurs consultent la fonction integercuberoot code> dans le package arithmoi .

Exemple: P>

ghci> import Math.NumberTheory.Powers.Cube
ghci> let x = 12345^3333
ghci> length $ show x
13637
ghci> isCube x
True
ghci> isCube (x+1)
False
ghci> length $ show $ integerCubeRoot x
4546


0 commentaires