Hello. Where is there an Agile Messageboard? On the first part of the Depot example, a price field shouldn''t be an integer right? (it should be more of a float since a price has decimals) Dominic Son -- Posted via http://www.ruby-forum.com/.
On 6/8/06, Dominic Mr <dominicson@gmail.com> wrote:> Hello. > > Where is there an Agile Messageboard?There''s an errata board here: http://books.pragprog.com/titles/rails2/errata> On the first part of the Depot example, a price field shouldn''t be an > integer right? (it should be more of a float since a price has decimals)Hm, to be honest, I don''t remember what they did in the book, but it''s probably correct. Many people prefer to store currency as pennies (sometimes wrapped in a Money class) to avoid the precision / rounding errors that result when performating mathematical operations on floating point integers. Have you ever seen the movie "Office Space"? :) -Pawel
Damn, you are correct about the integer. the problem is when people put in decimals, an error occurs because integers shouldn''t have decimals. So i''m gonna do something ghetto (or smart?) and have 2 fields, one for the dollar and the other for the cents, concatinate them, and call the dollar function to properly format the price. If someone has a more saine way, please let me know. Thanks again Pawl Dominic>> On the first part of the Depot example, a price field shouldn''t be an >> integer right? (it should be more of a float since a price has decimals) > > Hm, to be honest, I don''t remember what they did in the book, but it''s > probably correct. Many people prefer to store currency as pennies > (sometimes wrapped in a Money class) to avoid the precision / rounding > errors that result when performating mathematical operations on > floating point integers. Have you ever seen the movie "Office Space"? > :) > > -Pawel-- Posted via http://www.ruby-forum.com/.
Damn, you are correct about the integer. the problem is when people put in decimals, an error occurs because integers shouldn''t have decimals. So i''m gonna do something ghetto (or smart?) and have 2 fields, one for the dollar and the other for the cents, concatinate them, and call the dollar function to properly format the price. If someone has a more sane way, please let me know. Thanks again Pawl Dominic>> On the first part of the Depot example, a price field shouldn''t be an >> integer right? (it should be more of a float since a price has decimals) > > Hm, to be honest, I don''t remember what they did in the book, but it''s > probably correct. Many people prefer to store currency as pennies > (sometimes wrapped in a Money class) to avoid the precision / rounding > errors that result when performating mathematical operations on > floating point integers. Have you ever seen the movie "Office Space"? > :) > > -Pawel-- Posted via http://www.ruby-forum.com/.
On Thu, 2006-06-08 at 10:00 +0200, Dominic Mr wrote:> Hello. > > Where is there an Agile Messageboard? > > On the first part of the Depot example, a price field shouldn''t be an > integer right? (it should be more of a float since a price has decimals) > > Dominic Son >One of the classical errors of computer science is to use floats for currency. The first stock exchange program was shut down after a day due to rounding errors because the programmers used floats. By the end of the day, the rounding errors amounted to several thousand dollars. Instead of float, use fixed point notations. In essence, use a BigInt (or whatever the 64 bit data type is in Ruby) to count units at the precision you want, and divide by the appropriate factor to get the dollars for display. Gasoline is priced to the 1/100th of a penny, so counting money to $0.0001 and dividing by 10,000 to get dollars is a common idiom. The reason for this is because the IEEE floating point standard is a limited precision base 2 standard. Base 10 fractions often do not represent cleanly as base 2 binamals (for lack of a better term), and require more than the precision that the standards allow. Express 31/100 (decimal) as a decimal = 0.31 Express 31/100 (decimal) as a binamal = 0.0.010011111 .... Does this help?
On Jun 8, 2006, at 5:19 AM, David Johnson wrote:>> On the first part of the Depot example, a price field shouldn''t be an >> integer right? (it should be more of a float since a price has >> decimals) >> >> Dominic Son >> > One of the classical errors of computer science is to use floats for > currency. The first stock exchange program was shut down after a day > due to rounding errors because the programmers used floats. By the > end > of the day, the rounding errors amounted to several thousand dollars.In PostgreSQL, we use the decimal() or numeric() datatypes, which are essentially a restricted floats. For example: price DECIMAL(8,2). Not sure what the current equivalent is in MySQL. Robby -- Robby Russell Founder & Executive Director PLANET ARGON, LLC Ruby on Rails Development, Consulting & Hosting www.planetargon.com www.robbyonrails.com +1 503 445 2457 +1 877 55 ARGON [toll free] +1 815 642 4968 [fax]
Robby Russell wrote:> On Jun 8, 2006, at 5:19 AM, David Johnson wrote: > >> of the day, the rounding errors amounted to several thousand dollars. > In PostgreSQL, we use the decimal() or numeric() datatypes, which are > essentially a restricted floats. > > For example: price DECIMAL(8,2). > > Not sure what the current equivalent is in MySQL.I dunno either, but the design is not agnostic. I suppose that''s OK in some circumstances, but the general method of maintaining an integer of cents and converting on the fly to dollars is a workable one for most if not all databases. Bill -- Posted via http://www.ruby-forum.com/.
The implementation of the SQL92 decimal type is up to the database implementation. But, it is required to exhibit certain behaviors such as no rounding errors due to binary/decimal conversions. Typically, it is stored either as (a) an integer with the scaling factor applied in math and display functions, or (b) as a BCD fixed point representation. The solution I suggested is a low-level implementation of (a). I would be surprised if a mature and reliable product such as postgres implemented this as a "restricted float". The entire initial purpose of the DECIMAL (size, scale) type was to handle currency, which is not handled correctly by any binary fraction representation. DECIMAL is more akin to the PIC 9(8,2) type from COBOL, to use the same example you did. Someone should check the code, since postgres is open source. Java has a BigDecimal class that handles this. What would it take to add BigDecimal to the Ruby repertoire? On Thu, 2006-06-08 at 06:45 -0700, Robby Russell wrote:> On Jun 8, 2006, at 5:19 AM, David Johnson wrote: > > >> On the first part of the Depot example, a price field shouldn''t be an > >> integer right? (it should be more of a float since a price has > >> decimals) > >> > >> Dominic Son > >> > > One of the classical errors of computer science is to use floats for > > currency. The first stock exchange program was shut down after a day > > due to rounding errors because the programmers used floats. By the > > end > > of the day, the rounding errors amounted to several thousand dollars. > > In PostgreSQL, we use the decimal() or numeric() datatypes, which are > essentially a restricted floats. > > For example: price DECIMAL(8,2). > > Not sure what the current equivalent is in MySQL. > > Robby > > -- > Robby Russell > Founder & Executive Director > > PLANET ARGON, LLC > Ruby on Rails Development, Consulting & Hosting > > www.planetargon.com > www.robbyonrails.com > > +1 503 445 2457 > +1 877 55 ARGON [toll free] > +1 815 642 4968 [fax] > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails