9
votes

Comment puis-je tourner un flotteur à un nombre spécifié de chiffres significatifs dans Ruby?

Ce serait bien d'avoir un équivalent de fonction dans RUBY.

Par exemple: P>

>> (11.11).signif(1)
10
>> (22.22).signif(2)
22
>> (3.333).signif(2)
3.3
>> (4.4).signif(3)
4.4 # It's usually 4.40 but that's OK. R does not print the trailing 0's
    # because it returns the float data type. For Ruby we want the same.
>> (5.55).signif(2)
5.6


1 commentaires

Cette question serait-elle appropriée pour scicomp.stackexchange.com ?


7 Réponses :


2
votes

Je ne vois rien de comme ça dans le flotteur. Float est surtout une enveloppe pour le type code> Native code> et compte tenu des problèmes binaires / décimaux habituels, je ne suis pas surpris que le flotteur ne vous permettait pas de manipuler les chiffres significatifs. Cependant, BigDecimal dans la bibliothèque standard comprend Des chiffres significatifs, mais encore une fois, je ne vois rien qui vous permet de modifier directement les chiffres significatifs dans un bigdecimal: vous pouvez le demander mais vous ne pouvez pas le changer. Mais vous pouvez kludger autour de cela en utilisant une version no-op du mul code> ou Ajouter code> Méthodes: p>

require 'bigdecimal'
a = BigDecimal.new('11.2384')
a.mult(1, 2) # the result is 0.11E2   (i.e. 11)
a.add(0, 4)  # the result is 0.1124E2 (i.e. 11.24)


2 commentaires

BigDecimal #New prend un deuxième paramètre qui limite le nombre de chiffres significatifs pour le nombre.


@jwadsack: Mais cela ne fonctionne que lors de la création d'un nouveau BigDecimal, vous ne pouvez pas modifier la valeur chiffre d'un bigdecimal existant. Je pense que c'est ce que je voulais dire par "Je ne vois rien qui vous permet de modifier directement les chiffres significatifs dans un bigdecimal".



2
votes

Vous recherchez probablement de Ruby's Decimal .

Vous pouvez alors écrire: xxx

ou si vous préférez utiliser la même syntaxe, ajoutez ceci en tant que fonction à la classe flottante comme ceci: xxx

utilisation serait Ensuite, soyez identique, c'est-à-dire xxx

pour l'utiliser, installez le gemme xxx


0 commentaires

14
votes

Il y a probablement un meilleur moyen, mais cela semble fonctionner bien:

class Float
  def signif(signs)
    Float("%.#{signs}g" % self)
  end
end

(1.123).signif(2)                    # => 1.1
(11.23).signif(2)                    # => 11.0
(11.23).signif(1)                    # => 10.0


5 commentaires

Brillant! C'est le spécificateur "G" de Printf (A.K.A Sprintf, A.K.A%), puis jeté à flotteur! Brillant!


Cette mise en œuvre devrait être intégrée à Ruby. Est-ce que quelqu'un se soucie de soumettre un patch?


Attendre. Une nuance: (5.55) .Signif (2) # devrait être => 5.6 mais donne 5,5


Je suis plus de mi-chemin à une bonne demande de traction à Ruby 1.9 ( Github.com/alevchuk/ RUBY / COMMIT / BC2253 )! Mais besoin de prendre soin de (5.55) .Signif (2) # => 5.6


Je pense à adopter / intégrer ce code de R, SVN .r-project.org / r / trunk / src / nmath / fprec.c dans le chiffrement.c



-2
votes

Utilisez Sprintf si vous souhaitez imprimer des zéros de suivi

2.0.0-p353 :001 > sprintf "%.3f", 500
 => "500.000"
2.0.0-p353 :002 > sprintf "%.4f", 500
 => "500.0000"
2.0.0-p353 :003 >


0 commentaires

3
votes

Certaines des réponses et commentaires précédentes ont fait allusion à cette solution, mais c'est ce qui a fonctionné pour moi:

# takes in a float value and returns another float value rounded to 
# given significant figures.    
def round_to_sig_figs(val, sig_figs)
  BigDecimal.new(val, sig_figs).to_f
end


0 commentaires

1
votes

La réponse de BLOU91 est presque là, mais elle renvoie une chaîne, au lieu d'un flotteur. Ceci ci-dessous fonctionne pour moi: xxx

de sorte que la fonction, xxx


1 commentaires

Cela tourne au nombre spécifique de décimales, mais ce qui est recherché est de se rendre à un nombre spécifique de chiffres significatifs.



6
votes

Voici une implémentation qui n'utilise pas de chaînes ou d'autres bibliothèques.

class Float
  def signif(digits)
    return 0 if self.zero?
    self.round(-(Math.log10(self).ceil - digits))
  end
end


0 commentaires