# The Agile Book Messageboard?

#1

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 S.

#2

On 6/8/06, Dominic Mr removed_email_address@domain.invalid 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

#3

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

#4

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

#5

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 S.

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?

#6

On Jun 8, 2006, at 5:19 AM, David J. 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.

Robby

Robby R.
Founder & Executive Director

PLANET ARGON, LLC
Ruby on Rails Development, Consulting & Hosting

www.robbyonrails.com

+1 503 445 2457
+1 877 55 ARGON [toll free]
+1 815 642 4968 [fax]

#7

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?

#8

Robby R. wrote:

On Jun 8, 2006, at 5:19 AM, David J. 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