Wenn ich dies in meiner Rails-Anwendung ausführen:Rails Präzision Fehler
SQL (0.3ms) SELECT SUM("transactions"."amount") AS sum_id FROM "transactions" WHERE (envelope_id = 834498537)
Und dieser Wert wird zurückgegeben:
<BigDecimal:1011be570,'0.2515999999 9999997E2',27(27)>
my_envelope.transactions.sum(:amount)
Diese SQL in den Protokolldateien angezeigt wird
Wie Sie sehen können, ist der Wert 25.159999. Es sollte 25.16 sein. Wenn ich dieselbe SQL in der Datenbank selbst ausführe, wird der korrekte Wert zurückgegeben.
Ich bin ein wenig verwirrt, weil ich weiß, dass es Präzisionsprobleme mit Floats gibt, aber es gibt ein BigDecimal zurück. Der SQL-Spaltentyp ist dezimal. Ich verwende sqlite3 (3.6.17) und sqlite3-ruby (1.3.2). Irgendwelche Ideen?
Update 1
Hier sind die Ergebnisse, wenn ich diese ausführen, um die SQLite3-Rubin-Schnittstelle direkt mit.
$ rails c test
Loading test environment (Rails 3.0.3)
irb(main):001:0> db = SQLite3::Database.new("db/test.sqlite3")
=> #<SQLite3::Database:0x5242020>
irb(main):002:0> db.execute("SELECT SUM(amount) FROM transactions WHERE envelope_id = 834498537")
=> [[25.159999999999997]]
Die Klasse dieser Nummer ist Float. Übrigens, die drei Zahlen, die es summiert, sind -40,25, 100 und -34,59.
Update 2
Nach mehr Forschung, es stellt sich heraus, dass dies die sqlite3 funktioniert genau so, wie ist. Es gibt ein Double (wie Ruby Float) an sqlite3-ruby zurück und sqlite3-ruby gibt es einfach als Float an Rails weiter. Dann konvertiert Rails es in BigDecimal, da der Spaltentyp dezimal ist. Vor Ruby 1.9 würde Ruby diese Zahl für uns runden und wir würden das Problem nicht sehen.
Bitte aktualisieren Sie Ihre Frage, um anzugeben, welchen Datenbankserver Sie verwenden und welchen Treiber Sie verwenden, um darauf zuzugreifen. – noodl
Dies ist in meiner Testumgebung mit sqlite3 (3.6.17) und ich verwende sqlite3-ruby (1.3.2). – dontangg
Ich vermute, dass sqlite3-ruby ein Float erzeugt, um den Wert des Aggregats zurückzugeben. Können Sie das Ergebnis in eine Zeichenfolge in der Abfrage umwandeln, um dies zu vermeiden? Ich weiß, dass es keine ideale Lösung ist, aber es wird zumindest helfen, das Problem zu isolieren. – noodl