Hi, On Sat, 16 Feb 2008 04:42:34 -0800 (PST) Alex Shulgin <alex.shulgin / gmail.com> wrote: > Very impressive! :-) Thank you for your comment! > IANAL, but you might want to add license notice to `decimal.c'. The > copyright line alone would mean no rights for users if they copy the > file out of the package (which includes the license text). Oh, you are right. I've been followed the style of the body's source code too much ;) I added the notices to my source, and released as 0.0.1. Thanks for pointing out. http://decimal.rubyforge.org/ > Just curious what made you develop another decimal library--is > BigDecimal unhackable or does your library uses totally different > approach, or something else? ;-) There are two reason for reinventing. The first is a note of discord in the interface of BigDecimal. As the recent discussions in the ruby-dev, BigDecimal needs far different usage than Numeric classes that have been built-in'ed and attached as the stdlib, before the 1.8. For instance, BigDecimal#{floor,round,ceil,truncate} returns a BigDecimal object, not an Integer. I and some core developer thought this behavior can confuse users who know about the same name methods in Float, but the author didn't change the spec. i.e., "BigDecimal("1.1").truncate.to_s" returns "0.1E1", not "1". In other places, many odd behaviors are surveyed from my point of view: - BigDecimal.mode is too complicated method only in BigDecimal, and it's not MT-safe - BigDecimal.limit is also non MT-safe, and you can't write like "BigDecimal.limit = 10" as other library does. - No one knows exact meaning of BigDecimal.new's second argument. - BigDecimal#{add,sub,mult,div}(b, n) is also characteristic feature only in BigDecimal, but it is only the alias of "a = b + c; a.round(n)" except you cannot direct rounding mode each time. - For the last reason, Numeric#div cannot behave like other Numerics; user need to be remember that semantics of BigDecimal#div can change by its arguments' number. - BigDecimal#to_s() returns far different format than other's. My feeling of wrongness is shared with Rails' implementation: > def to_s(format="F") > _original_to_s(format) > end - As you see, BigDecimal#to_s can take one argument for formatting, but the grammer is totaly unique so users cannot make good use of their experiences. - BigDecimal#inspect and #precs returns internal array size, but who wants to know about private situations? Bignum never show it, accoding to the principle of encapsulation. - BigDecimal#sign is also original feature that can return "NaN" or "Infinity", but I don't think these are "signs." I guess the spec is introduced from the naked implementation, and I don't think it's the right way to design the interfaces. - BigDecimal#split is straight destructive interface for the OOP. - We have BigDecimal#**, but why BigDecimal#power is exist? The method that have such name is not exist in other's. - You should write like "x.sqrt" not similar to other's style, "Math.sqrt(x)" or "include Math; sqrt(x)". - If you need to convert BigDecimals to other Numerics each other, you also need to "require 'bigdecimal/util'" every time. In contrast, Rational/Complex defines necessity methods automatically. - etc, etc... I may lose some reasons that needed to write here. But anyway, I decided to redesign it. (The features that lack in Decimal will be written from now on, of course!) You may be already tired to read (sorry ;-), but I've never say about the second reason. It is, to avoid the "maintaining of reinvention" anymore. (Some person may call this "DRY principle") As D. E. Knuth said is his book[1], it is very easy to implement multi-precision decimal library if you have the library for the big integers. Most lines of BigDecimal make effort to _reinvent_ multi-precision integers, but, as you know, we _already_ have Bignums and it is exported as C API as rb_big_*(). Using this, I implemented nothing about complex problems as you see in decimal.c: > #define INUM_PLUS(a, b) (FIXNUM_P(a) ? fix_plus(a, b) : rb_big_plus(a, b)) You may feel this is "totally different approach" than BigDecimal's. The code size of Decimal is over 3 times smaller than BigDecimal's one. I believe the reinvention is worth enough if it contributes simplification. In addition, we can receive benefits of Bignum's stability and optimization, that are acquired in 13 years as Ruby's built-in library. There is FFT patch for multiplication of huge value in ruby-dev already. The summary of the second reason: "There are two choices here. One is 13-years matured and well-used, another is only 5 years old and used optionally. Which do you want?" I chose the former. [1] Donald E. Knuth: The Art of Computer Programming, Volume 2: Seminumerical Algorithms (3rd Edition) [978-0201896848] -- Tadashi Saito # sorry for too long and broken english article :-p