Just plain crap?

M

mike3

Hi.

I was programming this thing, and for some reason this just doesn't
"feel" right:

--
Primer on what this is supposed to be.

1. First of all, "u8" = unsigned char, "s16" = signed short, "s32" =
signed long,
"DIGIT32PTR" = DIGIT32 *, and DIGIT32 = unsigned long = "u32",

2. "BigFloat" = "big" (as in, multiprecision) "float"ing point number,

3. sign field = sign (1 for negative, 0 for positive),

4. err = error flag (if a computation fails, this is set.),

5. exp = exponent (from -32768 to 32767),

6. length = length of number in DIGIT32s,

7. digits = pointer to array of "length"'s worth of DIGIT32s that
holds
the significand of the number, least significant first -- MSB is
always
1 for normalized representation. This is allocated by the
constructors,
and freed by the destructors (BigFloat() and ~BigFloat(),
respectively).

8. All the operators there are comparison, addition, subtraction,
multiplication, and division.

9. "FG3DError" is a type used to return error values when the given
operation fails.
--

--- begin big long and crappy piece of code ---
class BigFloat {
private:
/* Data fields */
u8 sign;
u8 err;
s16 exp;
int length;
DIGIT32PTR digits;

/* Friends */
friend FG3DError FG3DMPFloat_Normalize(BigFloat *);
friend FG3DError FG3DMPFloat_Copy(BigFloat *, const BigFloat *);
friend FG3DError FG3DMPFloat_AddUnsigned(BigFloat *, const
BigFloat *, const BigFloat *);
friend FG3DError FG3DMPFloat_SubUnsigned(BigFloat *, const
BigFloat *, const BigFloat *);
friend FG3DError FG3DMPFloat_MulUnsigned(BigFloat *, const
BigFloat *, const BigFloat *);
friend FG3DError FG3DMPFloat_MulUnsignedSmall(BigFloat *, const
BigFloat *, DIGIT32);
friend FG3DError FG3DMPFloat_DivUnsigned(BigFloat *, const
BigFloat *, const BigFloat *);
friend FG3DError FG3DMPFloat_DivUnsignedSmall(BigFloat *, const
BigFloat *, DIGIT32);
friend FG3DError FG3DMPFloat_CmpUnsigned(int *, const BigFloat
*, const BigFloat *);
friend FG3DError FG3DMPFloat_CmpUnsignedSmall(int *, const
BigFloat *, DIGIT32);
friend FG3DError FG3DMPFloat_Add(BigFloat *, const BigFloat *,
const BigFloat *);
friend FG3DError FG3DMPFloat_Sub(BigFloat *, const BigFloat *,
const BigFloat *);
friend FG3DError FG3DMPFloat_Mul(BigFloat *, const BigFloat *,
const BigFloat *);
friend FG3DError FG3DMPFloat_MulSmallU(BigFloat *, const
BigFloat *, u32);
friend FG3DError FG3DMPFloat_MulSmallS(BigFloat *, const
BigFloat *, s32);
friend FG3DError FG3DMPFloat_Div(BigFloat *, const BigFloat *,
const BigFloat *);
friend FG3DError FG3DMPFloat_DivSmallU(BigFloat *, const
BigFloat *, u32);
friend FG3DError FG3DMPFloat_DivSmallS(BigFloat *, const
BigFloat *, s32);
friend FG3DError FG3DMPFloat_Cmp(int *, const BigFloat *, const
BigFloat *);
friend FG3DError FG3DMPFloat_CmpSmallU(int *, const BigFloat *,
u32);
friend FG3DError FG3DMPFloat_CmpSmallS(int *, const BigFloat *,
s32);
friend FG3DError FG3DMPFloat_PrintBin(LPTSTR, BigFloat *);

/* Private members */
FG3DError Init(int); /* initialize to a given
precision */
FG3DError InitNoZero(int); /* initialize to a given
precision with no zeroize prep */
FG3DError EquateUI(u32); /* equate to unsigned
integer */
FG3DError EquateSI(s32); /* equate to signed
integer */
FG3DError EquateBF(const BigFloat *); /* equate to another
BigFloat */
public:
BigFloat(); /* default constructor */
BigFloat(u32, int); /* construct to unsigned
small int with given precision */
BigFloat(s32, int); /* construct to signed
small int with given precision */
BigFloat(const BigFloat &); /* construct to another
BigFloat */
BigFloat(BOOL, int); /* construct without
initial zeroization (DANGEROUS!) */
~BigFloat(); /* default destructor */
DIGIT32 GetDigit(int); /* get a digit */
void SetDigit(DIGIT32, int); /* set a digit */
s16 GetExponent(); /* get exponent */
void SetExponent(s16 newexp); /* set exponent */
u8 GetSign(); /* get sign */
void SetSign(u8 newsign); /* set sign */
int GetLength(); /* get length */
FG3DError GetUI(u32 *); /* get unsigned integer
representation */
FG3DError GetSI(s32 *); /* get signed integer
representation */

/* Overloaded operators */
friend BOOL operator>=(const BigFloat &, const BigFloat &);
friend BOOL operator>=(const BigFloat &, const u32);
friend BOOL operator>=(const BigFloat &, const s32);
friend BOOL operator>(const BigFloat &, const BigFloat &);
friend BOOL operator>(const BigFloat &, const u32);
friend BOOL operator>(const BigFloat &, const s32);
friend BOOL operator==(const BigFloat &, const BigFloat &);
friend BOOL operator==(const BigFloat &, const u32);
friend BOOL operator==(const BigFloat &, const s32);
friend BOOL operator<(const BigFloat &, const BigFloat &);
friend BOOL operator<(const BigFloat &, const u32);
friend BOOL operator<(const BigFloat &, const s32);
friend BOOL operator<=(const BigFloat &, const BigFloat &);
friend BOOL operator<=(const BigFloat &, const u32);
friend BOOL operator<=(const BigFloat &, const s32);
BigFloat & BigFloat::eek:perator=(const BigFloat &);
BigFloat & BigFloat::eek:perator=(u32);
BigFloat & BigFloat::eek:perator=(s32);
const BigFloat & BigFloat::eek:perator+=(const BigFloat &);
friend BigFloat operator+(const BigFloat &, const BigFloat &);
const BigFloat & BigFloat::eek:perator-=(const BigFloat &);
friend BigFloat operator-(const BigFloat &, const BigFloat &);
const BigFloat & BigFloat::eek:perator*=(const BigFloat &);
const BigFloat & BigFloat::eek:perator*=(u32);
const BigFloat & BigFloat::eek:perator*=(s32);
friend BigFloat operator*(const BigFloat &, const BigFloat &);
friend BigFloat operator*(const BigFloat &, u32);
friend BigFloat operator*(const BigFloat &, s32);
friend BigFloat operator*(u32, const BigFloat &);
friend BigFloat operator*(s32, const BigFloat &);
const BigFloat & BigFloat::eek:perator/=(const BigFloat &);
const BigFloat & BigFloat::eek:perator/=(u32);
const BigFloat & BigFloat::eek:perator/=(s32);
friend BigFloat operator/(const BigFloat &, const BigFloat &);
friend BigFloat operator/(const BigFloat &, u32);
friend BigFloat operator/(const BigFloat &, s32);
friend BigFloat operator/(u32, const BigFloat &);
friend BigFloat operator/(s32, const BigFloat &);
};
--- end big long crappy piece of code ---

Is this thing total crap? For example, is it bad to have so many
friends in there
like that?! I'd like you to laugh and giggle at this, and hopefully
offer a detailed,
but useful, critique (not a flame, but a good critique of the code).

This is my first attempt at doing something serious with C++ (I've
done a lot of
C before, but not much C++), so, naturally, if I totally effed it all
up I would not
be surprised. But I'd like to at least know...
 
V

Victor Bazarov

mike3 said:
Hi.

[...good questions, valid questions, regarding BigFloat UDT...]

Please don't use a double-dash line to separate pieces of your message,
some crappy newsreaders treat them as signature separators and throw
away any text after them when quoting your message. I am using one of
those crappy newsreaders, and too lazy to manually quote the whole
thing to comment on it in detail.

Regarding your code: I think it _could_ be distilled a bit, but as it
stands now, it's fine. A bit verbose, perhaps, but fine. You could
pick better (maybe shorter) names for your errors (by creative use of
namespaces, for example). You could reduce the number of overloaded
arithmetic and comparison operators by introducing special c-tors from
'u32' or 's32' types.

Remeber, that this code, once it's written, debugged, and published,
in most cases is going to be looked at only by the compiler. If you
feel up to it, you can scare the sh!t out of yourself by looking at
the standard library implementation of 'std::set', for example.

V
 
M

mike3

mike3 said:
[...good questions, valid questions, regarding BigFloat UDT...]

Please don't use a double-dash line to separate pieces of your message,
some crappy newsreaders treat them as signature separators and throw
away any text after them when quoting your message. I am using one of
those crappy newsreaders, and too lazy to manually quote the whole
thing to comment on it in detail.

Well alright. Would stars (*) work?
Regarding your code: I think it _could_ be distilled a bit, but as it
stands now, it's fine. A bit verbose, perhaps, but fine. You could
pick better (maybe shorter) names for your errors (by creative use of
namespaces, for example). You could reduce the number of overloaded
arithmetic and comparison operators by introducing special c-tors from
'u32' or 's32' types.

However it's slower, at least for small numbers. See, the constructor
has to both allocate the memory and make the number (and normalize
it too to boot!). Even if you optimize it it's still going to be
slower.
Then when you do not use the thing again, it throws it away. I suppose
I could go and keep around a few "little" BigFloats to hold the
numbers but that just seems weird to me. (Like if my algorithm needs
to multiply by 2, keeping a BigFloat labeled "Two" around there just
seems odd.)
Remeber, that this code, once it's written, debugged, and published,
in most cases is going to be looked at only by the compiler. If you
feel up to it, you can scare the sh!t out of yourself by looking at
the standard library implementation of 'std::set', for example.

Where can I find that? It must look really awful.
 
V

Victor Bazarov

mike3 said:
[..] If you
feel up to it, you can scare the sh!t out of yourself by looking at
the standard library implementation of 'std::set', for example.

Where can I find that? It must look really awful.

Start with <set> header (which is most likely just a file somewhere
on your hard drive).

V
 
J

James Kanze

mike3 wrote:
[...good questions, valid questions, regarding BigFloat UDT...]
Please don't use a double-dash line to separate pieces of your message,
some crappy newsreaders treat them as signature separators and throw
away any text after them when quoting your message. I am using one of
those crappy newsreaders, and too lazy to manually quote the whole
thing to comment on it in detail.
Well alright. Would stars (*) work?

Even three hyphens.

[...]
That statement is simply false. Hopefully, at least, the code
will be maintained.
Where can I find that? It must look really awful.

It's part of the your compiler. It often doesn't look too good,
but usually at least, just because of the naming conventions
that the standard requires. For the rest, the implementations
I've looked at are a good deal cleaner than a lot of the code I
see elsewhere.
 
B

BobR

James Kanze wrote in message...
It's part of the your compiler. It often doesn't look too good,

It's like that old song, " ....she may be ugly, but she sure can cook.".
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,086
Latest member
ChelseaAmi

Latest Threads

Top