Boost logo

Boost :

From: Ilya Buchkin (elias_at_[hidden])
Date: 2003-07-17 17:51:49


Bill Seymour says: (Thursday, 17 July, 2003 8:03)
>
> 1. You want the scale to be a template parameter so that it's part
> of the type. I've just raised this issue again; and I expect
> there to be some discussion about it. Stay tuned. 8-)

I sure will :) Thanks

> 3. You want the internal representation to be a single 64-bit
> integer to make the object smaller. Why?

My use case - the database framework that I have.
Query result is returned as a number of rows * number of columns.
Each data item is a t_variant, which holds value of one of types.
Presently all [scalar] data types fit into eight bytes.
This one COULD too. Otherwise I am looking for significantly
higher memory usage, consequently swapping to HDD, etc.

    struct t_variant
        {
        union { // 8 bytes
            int value_int_;
            t_string value_string_; // sort-of pointer to
std::string,
                                                        // strings stored
separately
            t_datetime value_datetime_;
            t_decimal value_decimal_; // currently "typedef double" :(((
            };
        enum { .... } type_; // 2 bytes
        };
    struct t_datarow
        {
        std::vector< t_variant > data_; // well, almost like this
        }
    struct t_query_result
        {
        std::vector< t_datarow > data_; // well, almost like this
        }

> For efficiency? Do you think it would be faster to calculate
> the representation of unity for each operation?

True, it would not.
BUT luckily this isn't the only alternative, right? Consider this:

    static int ones_for_all_scales_[ max_scale ] = { 1, 10, 100, 1000,
10*1000, ... };

I have not checked if that would work (I think it should), because
it should not even be needed if the scale (and consequently the unity
a.k.a. "one") becomes part of the type.

> For decreased memory usage? Are you doing embedded systems work?

Yes, please see my use case above.
No, I don't think it's called "embedded".

> Somebody said, "Premature optimization is the root of all evil."
> I can't remember who that was (Knuth? Djikstra?); but somebody
> else on the list will probably tell us.

I think it's not premature.
My database application handles large volumes of data, and the sizes
of data make difference. Either I have to extend the size of t_variant,
or I have to store decimal as non-scalar type (i.e. like strings,
via pointer to separate storage) which also has its penalties.

I do think such basic value type has to be done carefully as to not
introduce obvious inefficiencies on such low level.

> 2. You also want the rounding mode to be part of the type. That
> binds the rounding mode to the operand instead of to the
> operator; but I've already chosen the latter. We could reopen
> that discussion if you want to; but I haven't gotten any other
> complaints.

This is minor issue by itself.
My major issue is that rounding to the scale of operand occurs
*in process* of calculations. Consider this:
    boost::numeric::decimal a( 1, "1.5" ), b( 1, "1.5" ), c( 2 );
    c = a * b; // should be = 2.25
I would like to have c == 2.25, but with your current implementation
it will be 2.20 (because rounding would be applied to a result of
multiplication, based on scale of first argument).
You can also see my real-life example from the first letter:
I iterate through items of invoice and accumulate tax. I do NOT want
rounding take place while I do these claculations, I want it to apply
only to the final result.

What I suggest is that we need two classes:
1. template-based for storage, parameterized by scale (and then possibly
   by rounding policy), and optimized for size.
2. non-template, for temporary results of calculations, optimized
   for precision and speed of calculations.

> 4. I haven't looked at your example code in detail yet; but at first
> glance, it looks like you're confusing the precision (the maximum
> number of representable digits) with the scale (the number of
> digits to the right of the decimal point).

*Even if* I confused one with another (btw I am not, but thank you
for being alert), would it change or invalidate my issues and questions?
I think they still apply as I formulated them.

Thanks & Best Regards.

Ilya Buchkin
MetaCommunications Engineering
mailto:elias_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk