#| Money Stuff Storing Floating Point values in an SQL database is *BAD*!: CL-DECK-BUILDER2> (with-connection (db) (mito:retrieve-by-sql (sxql:select ((:as 0.005 :real))))) ((:REAL 0.004999999888241291d0)) So I'm taking expert's advice and storing money as a fixed point integer with 100 divisions (cents). Deflate: Mito -> RDBMS Now with test suite! |# (in-package #:cl-deck-builder2.toolkit.money) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defgeneric currency-deflate (obj) (:documentation "CURRENCY-DEFLATE takes a NUMBER or a STRING and converts it into a fixed point number. ;; One Half Dollar / $0.50 / 50 Cents / These are all the same thing (CURRENCY-DEFLATE 1/2) => 50 (CURRENCY-DEFLATE 0.50) => 50 (CURRENCY-DEFLATE 0.5d0) => 50 (CURRENCY-DEFLATE \"1/2\") => 50 (CURRENCY-DEFLATE \"0.50\") => 50 (CURRENCY-DEFLATE \"0.5d0\") => 50 ;; One Dollar / $1.00 / 100 Cents / These are all the same thing (CURRENCY-DEFLATE 1) => 100 (CURRENCY-DEFLATE 1.00) => 100 (CURRENCY-DEFLATE 1.0d0) => 100 (CURRENCY-DEFLATE \"1\") => 100 (CURRENCY-DEFLATE \"1.00\") => 100 (CURRENCY-DEFLATE \"1.0d0\") => 100 ;; Ten Dollars / $10.00 / 1000 Cents / These are all the same thing (CURRENCY-DEFLATE 10) => 1000 (CURRENCY-DEFLATE 10.00) => 1000 (CURRENCY-DEFLATE 10.0d0) => 1000 (CURRENCY-DEFLATE \"10\") => 1000 (CURRENCY-DEFLATE \"10.00\") => 1000 (CURRENCY-DEFLATE \"10.0d0\") => 1000") (:method ((number number)) ;; CEILING or FLOOR? (ceiling (* 100 number))) (:method ((string string)) (currency-deflate (read-from-string (if (eq (char string 0) #\$) (subseq string 1) string))))) (defgeneric currency-inflate (obj) (:documentation "CURRENCY-INFLATE takes a NUMBER and converts it into a STRING representation of the fixed point amount of cents (100 cents per dollar) into \"$DD.CC\" format.") (:method ((number number)) (format nil "~$" (float (/ number 100)))))