Rounding issue

Discussion in 'Perl Misc' started by Marten Lehmann, Aug 17, 2009.

  1. Hello,

    I don't understand why

    perl -e 'print sprintf("%.0f", 1.5). "\n"'

    returns 2 as expected, but

    perl -e 'print sprintf("%.1f", 0.15). "\n"'

    returns 0.1, whereby I expected to get 0.2.

    What am I doing wrong? What do I have to do to get 0.2?

    Kind regards
    Marten Lehmann
    Marten Lehmann, Aug 17, 2009
    #1
    1. Advertising

  2. Marten Lehmann

    Jim Gibson Guest

    In article <>, Marten Lehmann
    <> wrote:

    > Hello,
    >
    > I don't understand why
    >
    > perl -e 'print sprintf("%.0f", 1.5). "\n"'
    >
    > returns 2 as expected, but
    >
    > perl -e 'print sprintf("%.1f", 0.15). "\n"'
    >
    > returns 0.1, whereby I expected to get 0.2.
    >
    > What am I doing wrong? What do I have to do to get 0.2?


    See the advice in 'perldoc -q round'

    Observe that

    perl -e '$x=0.15; printf "%.20f\n", $x;'

    produces:

    0.14999999999999999445

    so should round to 0.1.

    --
    Jim Gibson
    Jim Gibson, Aug 17, 2009
    #2
    1. Advertising

  3. Marten Lehmann <> wrote:
    >I don't understand why
    >
    >perl -e 'print sprintf("%.0f", 1.5). "\n"'
    >
    >returns 2 as expected, but
    >
    >perl -e 'print sprintf("%.1f", 0.15). "\n"'
    >
    >returns 0.1, whereby I expected to get 0.2.
    >
    >What am I doing wrong? What do I have to do to get 0.2?


    Print both numbers with 20 digits and note the difference.

    For further information please see 'perldoc -q 999' or revisit your
    notes on your "Basics of Computer Numerics" class.

    jue

    PS: you could argue that 1.5 should have been rounded down to 1 because
    the 1.5 is exactly 5 with all following digits being 0, but alas, that's
    not how it's implemented.

    jue
    Jürgen Exner, Aug 17, 2009
    #3
  4. Hello,

    > ~% perl -E'say sprintf "%.40f", 0.15'
    > 0.1499999999999999944488848768742172978818


    why isn't it stored as 0.150000000000000 internally?

    > This is less than 0.15, so it rounds to 0.1.


    This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    why 1.5 works different than 0.15 wuth just one floating point digit
    difference.

    >> What am I doing wrong? What do I have to do to get 0.2?

    >
    > Where is this number coming from? Why do you need it to round to 0.2?


    In this specific case I hardcoded it into the source. But in the real
    application it is coming from a database and then some tax calculations
    are done and in accounting every cent difference causes headaches.

    Why does

    perl -e 'print sprintf("%.1f", 0.10 + 0.05). "\n"'

    work fine?

    Kind regards
    Marten
    Marten Lehmann, Aug 17, 2009
    #4
  5. Marten Lehmann <> wrote:
    >> ~% perl -E'say sprintf "%.40f", 0.15'
    >> 0.1499999999999999944488848768742172978818

    >
    >why isn't it stored as 0.150000000000000 internally?
    >
    >> This is less than 0.15, so it rounds to 0.1.

    >
    >This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    >why 1.5 works different than 0.15 wuth just one floating point digit
    >difference.


    Please re-read your notes from "Basics of Computer Numerics".

    Hint: Typical computers are binary, they don't use the decimal system.

    >In this specific case I hardcoded it into the source. But in the real
    >application it is coming from a database and then some tax calculations
    >are done and in accounting every cent difference causes headaches.


    That is why using floating point numbers for accounting is A VERY Bad
    Idea(TM) and very strongly discouraged. Didn't your computer numerics
    teacher tell you so?

    >Why does
    >perl -e 'print sprintf("%.1f", 0.10 + 0.05). "\n"'
    >work fine?


    Again: print the result of that addition with 20 digits and you will see
    why.

    jue
    Jürgen Exner, Aug 17, 2009
    #5
  6. Marten Lehmann <> wrote:
    > > ~% perl -E'say sprintf "%.40f", 0.15'
    > > 0.1499999999999999944488848768742172978818


    > why isn't it stored as 0.150000000000000 internally?


    > > This is less than 0.15, so it rounds to 0.1.


    > This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    > why 1.5 works different than 0.15 wuth just one floating point digit
    > difference.


    Floating point numbers are stored as binary numbers. And, just
    like you can't write a lot of numbers in a 10 based system
    (e.g. one third) with a limited number of digits, you can't
    store a lot of numbers in a binary system with a limited
    number of bits. Thus the overwhelming majority of floating
    point numbers are only approximations. For example 0.1 looks
    like a simple number when written in a 10 based number system,
    but when you would try to write it in a 2 based system you
    would need an infinite number of bits. On the other hand,
    a number like 1.0/3.0 would require an infinite number of
    digits when written in a 10 based system but would be a
    very "simple" number when you would write in base 3. (In
    base 10 all rational numbers that are a fraction with the
    denominator being the product of a power of 2 and a power
    of 5 can be written with a limited number of digits, in
    base 2 only those that have a power of 2 as the denominator.)

    Thus, 1.5 can be stored precisely in base 2 with the limited
    number of bits you have for a floating point number while
    0.15 can't. Thus 0.15 can only be represented by an appro-
    ximation which then leads to the problem you observed.

    > >> What am I doing wrong? What do I have to do to get 0.2?

    > > Where is this number coming from? Why do you need it to round to 0.2?


    > In this specific case I hardcoded it into the source. But in the real
    > application it is coming from a database and then some tax calculations
    > are done and in accounting every cent difference causes headaches.


    > Why does


    > perl -e 'print sprintf("%.1f", 0.10 + 0.05). "\n"'


    Here a further problem with using floating point numbers
    is at work. Neither 0.1 nor 0.05 can be stored precisely.
    So you are already starting of with imprecise numbers. And
    when you add those imprecise numbers the errors can add up!
    And the more calculations you do the larger the error can
    become.

    In your example one result is that 0.15 isn't equal to
    0.1 + 0.05. Thus a rule of thumb is never to try to
    compare floating point numbers for equality since the
    result hardly ever is what you expect.

    But even with numbers that can be represented exactly there
    can be problems. On my machine I get

    jens@cm:~$ perl -e 'print sprintf("%.1f", 0.25). "\n"'
    0.2
    jens@cm:~$ perl -e 'print sprintf("%.1f", 0.75). "\n"'
    0.8

    While the 0.8 result for 0.75 is what one would expect,
    the 0.2 for 0.25 isn't. The explanation is probably that
    it's the result of rounding errors introduced when the
    digits to be displayed are calculated.

    If you want the precision you're looking for you probably
    shouldn't use floating point numbers at all! If you want
    e.g. 2 digits after the decimal point then "scale" your
    calculations by a factor of 100, so that everything can
    be done with integers.

    Welcome to the wonderful world of floating point calculations;-)

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Aug 17, 2009
    #6
  7. Hello,

    > Marten Lehmann <> wrote:
    >>> ~% perl -E'say sprintf "%.40f", 0.15'
    >>> 0.1499999999999999944488848768742172978818

    >> why isn't it stored as 0.150000000000000 internally?
    >>
    >>> This is less than 0.15, so it rounds to 0.1.

    >> This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    >> why 1.5 works different than 0.15 wuth just one floating point digit
    >> difference.

    >
    > Please re-read your notes from "Basics of Computer Numerics".


    although I know about the difference between an internal representation
    and the number itself, I don't want to care about that the whole day.
    All I'm expecting is the programming language to remember the precision
    I used when a value was stored. 1.5 is not an infinite value as 1/3.

    Kind regards
    Marten
    Marten Lehmann, Aug 17, 2009
    #7
  8. >>>>> "Marten" == Marten Lehmann <> writes:

    Marten> All I'm expecting is the programming language to remember the
    Marten> precision I used when a value was stored. 1.5 is not an infinite value
    Marten> as 1/3.

    But it is. The moment 0.15 is "stored", it's a truncation of an infinite
    binary value, and is therefore not precisely 0.15 any more.

    (And actually, 1.5 *can* be stored precisely, so you must've gotten mixed up
    in this thread.)

    print "Just another Perl hacker,"; # the original

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
    See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
    Randal L. Schwartz, Aug 17, 2009
    #8
  9. On 2009-08-17 20:41, Marten Lehmann <> wrote:
    >> Marten Lehmann <> wrote:
    >>>> ~% perl -E'say sprintf "%.40f", 0.15'
    >>>> 0.1499999999999999944488848768742172978818
    >>> why isn't it stored as 0.150000000000000 internally?
    >>>
    >>>> This is less than 0.15, so it rounds to 0.1.
    >>> This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    >>> why 1.5 works different than 0.15 wuth just one floating point digit
    >>> difference.

    >>
    >> Please re-read your notes from "Basics of Computer Numerics".

    >
    > although I know about the difference between an internal representation
    > and the number itself, I don't want to care about that the whole day.


    Then you shouldn't do numeric work.

    > All I'm expecting is the programming language to remember the precision
    > I used when a value was stored.


    You'll be disappointed. Almost no programming language does this. At
    least not for basic numeric types. Some programming languages may offer
    a "rational" type (Perl has "BigRat").

    > 1.5 is not an infinite value as 1/3.


    You mean "periodic", not "infinite". Infinite is for example the number
    of natural numbers.

    1/3 is a periodic number in base 10 or base 2.
    It is not a periodic number in base 3.

    1/10 is a periodic number in base 2 or base 3.
    It is not a periodic number in base 10.

    1/2 is a periodic number in base 3.
    It is not a periodic number in base 2 or 10.

    hp
    Peter J. Holzer, Aug 17, 2009
    #9
  10. Marten Lehmann <> wrote:
    > Hello,


    > > Marten Lehmann <> wrote:
    > >>> ~% perl -E'say sprintf "%.40f", 0.15'
    > >>> 0.1499999999999999944488848768742172978818
    > >> why isn't it stored as 0.150000000000000 internally?
    > >>
    > >>> This is less than 0.15, so it rounds to 0.1.
    > >> This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    > >> why 1.5 works different than 0.15 wuth just one floating point digit
    > >> difference.

    > >
    > > Please re-read your notes from "Basics of Computer Numerics".


    > although I know about the difference between an internal representation
    > and the number itself, I don't want to care about that the whole day.


    Then you better don't use floating point numbers;-)

    > All I'm expecting is the programming language to remember the precision
    > I used when a value was stored. 1.5 is not an infinite value as 1/3.


    And you don't have the problem with 1.5, you have it with 0.15,
    which is a number that requires an infinite number of bits to
    be represented exactly in binary...

    It's not a question of the programming language - you will have
    the same problem in all programming languages that allow you
    to use floating point numbers. The first thing is that the same
    problems also appears if you represent numbers in base 10 -
    1/3 is the simplest example - you're used to it and thus don't
    wonder what's going on. Of course, you can use Perl (or any
    other language) to represent numbers in a 10 based system
    (and some processors even have some kind of support for it,
    see for example BCD (binary coded decimals)). But you then
    have to write functions for all the arithmetic operators
    printing etc. etc. and the computation speed will probably
    be rather abysimal.

    But the fundamental problem remains. You have an infinite
    number of floating point numbers that must be represented
    with a limited number of bits. Thus except for an infinitely
    small fraction of them you have just approximations. And
    once you have only an approximation there's no going back to
    the exact number you started of with.

    Asking for 0.1 + 0.05 to be output after rounding as "0.2"
    when the numbers are represented in binary is exactly the
    same as asking for 2.0/6.0 + 1.0/6.0 to be output as "1"
    after rounding when using a base 10 representation with a
    limited number of digits - it simply can't be done. That
    you accept the problem when using base 10 but not when
    using base 2 is just a result of being used to the limi-
    tations of base 10 but less to that of base 2.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Aug 17, 2009
    #10
  11. Marten Lehmann

    Guest

    On Mon, 17 Aug 2009 20:08:16 +0200, Marten Lehmann <> wrote:

    >Hello,
    >
    >I don't understand why
    >
    >perl -e 'print sprintf("%.0f", 1.5). "\n"'
    >
    >returns 2 as expected, but
    >
    >perl -e 'print sprintf("%.1f", 0.15). "\n"'
    >
    >returns 0.1, whereby I expected to get 0.2.
    >
    >What am I doing wrong? What do I have to do to get 0.2?
    >
    >Kind regards
    >Marten Lehmann


    As Ben said, the 1,5 is not really 1.5 in floating point terms.

    However, this below gets what you want.

    If your application is accounting, and your doing discreet
    calculations that in PRINT you want them to add up to a correct
    "visual" total, then this is what you want.

    The reassignment of course is the $newval = sprintf();
    You must make sure you are only dealing with fractions of cent
    and that it would not be the case of it being used itteratively
    in a future calculation.

    At least, I wouldn't want my bank to.

    -sln
    =======================

    use strict;
    use warnings;

    my $f1 = 1.5;
    my $f2 = .15;

    print sprintf("%.0f", $f1). "\n";
    print sprintf("%.1f", $f2). "\n";
    print "\n";
    print sprintf("%.0f", (($f1 * 100)+5)/100 ). "\n";
    print sprintf("%.1f", (($f2 * 100)+5)/100). "\n";

    __END__
    Output:

    2
    0.1

    2
    0.2
    , Aug 18, 2009
    #11
  12. Marten Lehmann <> wrote:
    >> Please re-read your notes from "Basics of Computer Numerics".

    >
    >although I know about the difference between an internal representation
    >and the number itself, I don't want to care about that the whole day.
    >All I'm expecting is the programming language to remember the precision
    >I used when a value was stored. 1.5 is not an infinite value as 1/3.


    Yes, it is when stored in binary format as virtually all computers do.
    And it has nothing to do with the particular programming language but
    with how your typical computer works.

    Please re-read your notes from "Basics of Computer Numerics"

    jue
    Jürgen Exner, Aug 18, 2009
    #12
  13. Marten Lehmann

    Guest

    On Mon, 17 Aug 2009 16:19:40 -0700, wrote:

    >On Mon, 17 Aug 2009 20:08:16 +0200, Marten Lehmann <> wrote:
    >
    >=======================
    >
    >use strict;
    >use warnings;
    >
    >my $f1 = 1.5;
    >my $f2 = .15;
    >
    >print sprintf("%.0f", $f1). "\n";
    >print sprintf("%.1f", $f2). "\n";
    >print "\n";
    >print sprintf("%.0f", (($f1 * 100)+5)/100 ). "\n";
    >print sprintf("%.1f", (($f2 * 100)+5)/100). "\n";

    ^^
    I'm sorry these should be ' + .5'

    print sprintf("%.0f", (($f1 * 100) + .5)/100 ). "\n";
    print sprintf("%.1f", (($f2 * 100) + .5)/100). "\n";

    Now $f1,$f2 can be used with a common format string, like "%.1f", or "%.0f"
    and be consistant.

    -sln
    , Aug 18, 2009
    #13
  14. Marten Lehmann

    Guest

    On Mon, 17 Aug 2009 16:37:37 -0700, wrote:

    >On Mon, 17 Aug 2009 16:19:40 -0700, wrote:
    >
    >>On Mon, 17 Aug 2009 20:08:16 +0200, Marten Lehmann <> wrote:
    >>
    >>=======================
    >>
    >>use strict;
    >>use warnings;
    >>
    >>my $f1 = 1.5;
    >>my $f2 = .15;
    >>
    >>print sprintf("%.0f", $f1). "\n";
    >>print sprintf("%.1f", $f2). "\n";
    >>print "\n";
    >>print sprintf("%.0f", (($f1 * 100)+5)/100 ). "\n";
    >>print sprintf("%.1f", (($f2 * 100)+5)/100). "\n";

    > ^^
    >I'm sorry these should be ' + .5'
    >
    > print sprintf("%.0f", (($f1 * 100) + .5)/100 ). "\n";
    > print sprintf("%.1f", (($f2 * 100) + .5)/100). "\n";
    >
    >Now $f1,$f2 can be used with a common format string, like "%.1f", or "%.0f"
    >and be consistant.
    >
    >-sln
    >

    It can be generalized.
    It only works up to the width of the mantissa.
    Which is what 8 digits? So don't set the width to say 40.
    A width of 2 max should do fine.

    -sln
    ===============================
    use strict;
    use warnings;

    my $f1 = 1.5;
    my $f2 = .15;

    my ($n1,$n2) = (
    getFmtRound($f1,40),
    getFmtRound($f2,40)
    );

    print "$n1\n$n2\n\n";

    print getFmtRound($f1,0),"\n";
    print getFmtRound($f2,1),"\n";

    sub getFmtRound
    {
    my ($val,$width) = @_;
    my $fmt = "%.$width"."f";
    return sprintf $fmt,(($val * 10**($width))+.5)/(10**($width));
    }
    __END__

    1.5000000000000000000000000000000000000000
    0.1499999999999999900000000000000000000000

    2
    0.2
    , Aug 18, 2009
    #14
  15. Marten Lehmann

    Guest


    >use strict;
    >use warnings;
    >
    >my $f1 = 1.5;
    >my $f2 = .15;
    >
    >my ($n1,$n2) = (
    > getFmtRound($f1,40),
    > getFmtRound($f2,40)
    >);
    >
    >print "$n1\n$n2\n\n";
    >
    >print getFmtRound($f1,0),"\n";
    >print getFmtRound($f2,1),"\n";
    >
    >sub getFmtRound
    >{
    > my ($val,$width) = @_;
    > my $fmt = "%.$width"."f";
    > return sprintf $fmt,(($val * 10**($width))+.5)/(10**($width));

    ^^^ ^^
    return sprintf $fmt,(($val * 10**($width+1))+.5)/(10**($width+1));

    Hey sorry again, this should be $width+1. Have to affect only the last digit.
    -sln
    , Aug 18, 2009
    #15
  16. Marten Lehmann

    Doug Miller Guest

    In article <>, Marten Lehmann <> wrote:
    >Hello,
    >
    >> ~% perl -E'say sprintf "%.40f", 0.15'
    >> 0.1499999999999999944488848768742172978818

    >
    >why isn't it stored as 0.150000000000000 internally?
    >
    >> This is less than 0.15, so it rounds to 0.1.

    >
    >This is explains why 0.149 doesn't round to 0.2, but it doesn't explain
    >why 1.5 works different than 0.15 wuth just one floating point digit
    >difference.


    Of course it does. 1.5 has an exact binary representation, 0.15 does not.
    Doug Miller, Aug 18, 2009
    #16
  17. Hello,

    maybe I should change the question to:

    How can I force Perl to process certain calculations using decimals?
    There are special datatypes in Python and databases. Is there any in Perl?

    Ben proposed using the bignums pragma, but I'm afraid that this breaks
    something else in the code.

    Kind regards
    Marten
    Marten Lehmann, Aug 18, 2009
    #17
  18. Marten Lehmann <> wrote:
    > maybe I should change the question to:


    > How can I force Perl to process certain calculations using decimals?
    > There are special datatypes in Python and databases. Is there any in Perl?


    If you use just ints you should be fine since there aren't any
    rounding errors. There's no built-in BCD type or similar. But
    there seems to be rather new module

    http://search.cpan.org/~zefram/Math-Decimal-0.001/lib/Math/Decimal.pm

    for doing decimal arithmetic. Or have a look at

    http://search.cpan.org/~tels/Math-BigRat-0.22/lib/Math/BigRat.pm

    if you want as much precision as the amount of memory in your
    machine allows (note: I didn't use any of these modules, so
    I can't tell how well they work).

    > Ben proposed using the bignums pragma, but I'm afraid that this breaks
    > something else in the code.


    That you will need if the numbers you use ints and end up with
    are too large to be stored in a simple int.

    But what will do for you (if it's possible at all) depends on
    what exactly you want to do. Until now all we have seen is a
    few one-liners, what you need it for is still unclear.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Aug 18, 2009
    #18
  19. Hello,

    > But what will do for you (if it's possible at all) depends on
    > what exactly you want to do.


    I want to do financial calculations (nothing special, just simple things
    like adding items of an invoice, adding taxes, removing disagio from
    creditcard transactions etc.) and I want to be sure of correct results.

    So if a total with tax is $0.015, then I need it to be rounded to $0.02
    and not $0.01. Therefor, numbers need to be represented as they are and
    not the typical internal representation. I don't want to use cents as
    integers. Even cents will get odd numbers after the decimal point if you
    have to add e.g. 19% value added taxes. And even worser: The whole code
    would get bloated and the original intention of the code would be harder
    to understand if the whole source is full of "* 100" and "/ 100". In
    databases it is easy to define a decimal like (10,2): 10 digits before
    the point, 2 after it. It would be great to have this directly in Perl
    so that sprintf and other functions can still work with such values and
    variables, not only specific modules like Math::Decimal.

    Regards
    Marten
    Marten Lehmann, Aug 18, 2009
    #19
  20. Marten Lehmann

    Guest

    On Tue, 18 Aug 2009 20:04:37 +0200, Marten Lehmann <> wrote:

    >Hello,
    >
    >> But what will do for you (if it's possible at all) depends on
    >> what exactly you want to do.

    >
    >I want to do financial calculations (nothing special, just simple things
    >like adding items of an invoice, adding taxes, removing disagio from
    >creditcard transactions etc.) and I want to be sure of correct results.
    >
    >So if a total with tax is $0.015, then I need it to be rounded to $0.02
    >and not $0.01. Therefor, numbers need to be represented as they are and
    >not the typical internal representation. I don't want to use cents as
    >integers. Even cents will get odd numbers after the decimal point if you
    >have to add e.g. 19% value added taxes. And even worser: The whole code
    >would get bloated and the original intention of the code would be harder
    >to understand if the whole source is full of "* 100" and "/ 100". In
    >databases it is easy to define a decimal like (10,2): 10 digits before
    >the point, 2 after it. It would be great to have this directly in Perl
    >so that sprintf and other functions can still work with such values and
    >variables, not only specific modules like Math::Decimal.
    >
    >Regards
    >Marten


    I don't understand your big concern. Anytime you see numbers, decimal
    points, or anything printed in a view from a computer is a rounded
    representation of what the internal variable contains.

    Its just a view, its a one way snapshot of the contents of the variable.
    That doesen't affect the internal calculations. Indeed for percentage
    calculations, there is absolutely nothing wrong with floating point
    at all.

    When you have to display (have a view) where you think its necessary
    to show a correct image of the results of percentages as fractions of
    dollars (cents) then use a rounding translation that everybody and thier
    uncle uses.

    Why is it so hard?

    sub getFmtRound
    {
    my ($val,$width) = @_;
    my $fmt = "%.$width"."f";
    return sprintf $fmt,(($val * 10**($width+1))+.5)/(10**($width+1));
    }

    -sln
    , Aug 18, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. walala
    Replies:
    12
    Views:
    1,853
  2. valentin tihomirov

    rounding to integer

    valentin tihomirov, Feb 15, 2004, in forum: VHDL
    Replies:
    2
    Views:
    9,487
    Jonathan Bromley
    Feb 16, 2004
  3. Rounding Issue

    , Oct 30, 2007, in forum: Java
    Replies:
    3
    Views:
    427
    Roedy Green
    Oct 30, 2007
  4. Samuel Lown

    Unexpected BigDecimal rounding issue

    Samuel Lown, May 6, 2009, in forum: Ruby
    Replies:
    5
    Views:
    175
    Robert Klemme
    May 6, 2009
  5. Manu Sankala

    Yet another rounding issue

    Manu Sankala, Feb 21, 2010, in forum: Ruby
    Replies:
    3
    Views:
    108
    Manu Sankala
    Feb 21, 2010
Loading...

Share This Page