2015-12-18 6 views
8

in der Dokumentation von BigDecimal Klasse BezugOb String oder Integer in BigDecimal in Ruby verwenden

n,m = a.precs
prec kehrt Anzahl signifikanter Stellen (n) und maximale Anzahl signifikanter Stellen (m) von a.

Ich bin verwirrt von der folgenden Ausgabe bezogen auf BigDecimal.

require 'bigdecimal'  
BigDecimal.new('1').precs # => [9, 18] 
BigDecimal.new(1).precs # => [9, 27] 

ich kann nicht herausfinden, warum, wenn ein String übergeben wird, wird die maximale Anzahl der signifikanten Stellen weniger im Vergleich zu, wenn ein Fixnum übergeben wird.

Wird es auch zu Problemen bei der Genauigkeit kommen?

+0

Der Konstruktor nimmt ein zweites Argument, wenn Sie Konsistenz wollen: 'BigDecimal.new ('1', 27) .precs' zum Beispiel. Und die Dokumentation sagt, dass die "Anzahl der signifikanten Ziffern vom Anfangswert bestimmt wird", wenn Sie sie nicht selbst angeben. –

+0

@muistooshort Ihr Recht, dass wir das angeben können. Aber meine Frage war, warum die 'Precs' überhaupt anders sind? – abhinavmsra

+3

Hier sind weitere Datenpunkte. Die folgenden Beobachtungen beziehen sich auf Zeichenfolgen, die nur das Zeichen "1" enthalten (z. B. "111111") und Zahlen, deren Ziffern alle "1" sind (z. B. "111111"). Für weniger als 10 Zeichen wird "[9,18]" zurückgegeben. Für weniger als "10" Ziffern wird "[9,27]" zurückgegeben. Zwischen '10' und' 18' Zeichen * oder * Ziffern, '[18,27]' wird zurückgegeben (dh das gleiche Tupel wird für Strings und Zahlen zurückgegeben), zwischen '19' und einer größeren Anzahl von Zeichen oder Ziffern , [27,36] wird zurückgegeben. Nebenbei: Ich schlage vor, Sie fügen 'require 'bigdecimal'' zu Ihrem Code hinzu. –

Antwort

3

Wenn Sie C-Code lesen können, können Sie bei https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2509 beginnen - das ist der Initialisierer für jedes Objekt BigDecimal. Wenn Sie diesem Code bis zur nächsten Methode folgen, die BigDecimal_new ist, werden Sie feststellen, dass bei der Übergabe eines Integer-Arguments noch einige weitere Schritte durchlaufen werden müssen, bevor ein internes großes Dezimal-Objekt zugewiesen und erstellt wird, anstatt ein String-Argument zu übergeben.

In jedem Fall sollten Sie sich keine Sorgen um Genauigkeitsverlust machen - die signifikanten Ziffern-Attribute sind mehr wie Hinweise als absolute Werte. Sogar die Dokumentation erwähnt es: The actual number of significant digits used in computation is usually larger than the specified number.