Tuesday, April 6, 2010

comp.lang.c - 25 new messages in 8 topics - digest

comp.lang.c
http://groups.google.com/group/comp.lang.c?hl=en

comp.lang.c@googlegroups.com

Today's topics:

* lvalues and rvalues - 6 messages, 4 authors
http://groups.google.com/group/comp.lang.c/t/0bcad112a3ad97f0?hl=en
* Computing a*b/c without overflow in the preprocessor - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/1049c69de2e8ea27?hl=en
* C the complete nonsense - 12 messages, 5 authors
http://groups.google.com/group/comp.lang.c/t/fee08dfa5e4cbaaa?hl=en
* Personal attacks by moderators in a moderated group are unprofessional - 2
messages, 2 authors
http://groups.google.com/group/comp.lang.c/t/fcaffc6b8db42751?hl=en
* Looking for NNTP server - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/b27bbc7383c9d155?hl=en
* Blonde C jokes - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/ad1c486bad884e91?hl=en
* Even more errors in Schildt's books. - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/093065c470204c4c?hl=en
* Bill Cunningham and sockets for the past six years - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/d619226f82f56065?hl=en

==============================================================================
TOPIC: lvalues and rvalues
http://groups.google.com/group/comp.lang.c/t/0bcad112a3ad97f0?hl=en
==============================================================================

== 1 of 6 ==
Date: Tues, Apr 6 2010 2:11 pm
From: "Morris Keesan"


On Tue, 06 Apr 2010 15:59:01 -0400, Keith Thompson <kst-u@mib.org> wrote:

> int x;
...
> Whether an expression is an lvalue or not is relevant only in some
> contexts, namely those contexts that require an lvalue. The most
> obvious example is the left side of an assignment. For example:
> x = 42;
> is valid, because x is an value

[obviously a slip of the keyboard, and intended to read "x is an lvalue"].

The other obvious example of a context that requires an lvalue is the
operand of the unary & operator. An lvalue is something that has an
address, so

&x

is a valid expression, while

&42

is not. Given

const int y = 42;

y is an lvalue, so &y is a valid expression, while &42 is not, even though
y cannot appear on the left side of an assignment operator (because it's
an unmodifiable lvalue).


--
Morris Keesan -- mkeesan@post.harvard.edu


== 2 of 6 ==
Date: Tues, Apr 6 2010 3:24 pm
From: "bartc"

"Nicklas Karlsson" <karlsson.nicklas@gmail.com> wrote in message
news:687e94da-dbcf-4dfe-b2cf-db12874a2f14@u31g2000yqb.googlegroups.com...
> Hello,
>
> I am quite confused about this, so I split it in to subquestions, here
> we go:
>
> 1. Is an lvalue the expression itself, or is it the result yielded by
> evaluation of an expression? Take this for example: int i = 10; int *p
> = &i; and then dereference: *p; is the expression "*p" the thing you
> call an lvalue or is an lvalue the result yielded by evaluating that
> lvalue-expression?

A rule of thumb might be: if you can apply the & operator to it
(address-of), then it can be an lvalue (with a few exceptions such as
function names)

But here:

int A,B;

A = B;

Both A,B could be lvalues, but only A is being used as one. (In assembly,
you will find little difference between how the two are treated:

mov [A],[B] # assuming memory-to-memory allowed

(I'm done a bit of compiler work; I would handle the assignment above as
follows:

*(&A) = B;

Ie. apply address-of to the left-hand-side, then dereference. The * and &
cancel out, but it has now verified the left-side is an lvalue. If you try
and write:

56 = B;

this obviously won't work (since &56 is not allowed).)

>
> 2. Rvalues, is rvalues the result yielded by an rvalue-expression, or
> is it the expression itself? If its the result yielded by evaluation
> of an rvalue-expression is an rvalue a plain value?

There will be some technical interpretation somewhere or other. To me, the
rvalue would be the result of evaluating the expression: a value with a
type. (In some languages, this is not quite so clear-cut; fortunately this
is C.)

> 3. I am quite sure that in a conversion from C to Assembly an lvalue-
> expression yields an an address when evaluated,

Try looking at some assembly output.

> however, in C an
> lvalue seems to have properties, an address and a type, again, using
> the example of *p, the lvalue will be of type "int", if an lvalue-
> expression always yields an address when evaluated, C could keep track
> of the addresses type, so if the lvalue (the address) is "0x0" and C
> knows the addresses type is "int*" does C everytime it encounters that
> lvalue say "here you can only read/write an int because the address is
> int*" and therefor the type of the lvalue is "int"? But if its just an
> address how can it have a type other then the addresses type? That
> makes me wonder what an lvalue acctually is in C, how should I think
> about it? It's something that keeps track of an address and type?

int A=78;

Here, several things are happening:

'A' A is really the name of a location, or address, containing 78.
Let's say this is address 0x400100.
The type of 'A' is pointer-to-int. However, C automatically
dereferences such names (in common with other languages), so:

A Will dereference the 'A' address with value 0x400100, to fetch
the value 78. This is now type int.

&A This overrides the automatic dereference to allow access to the
address. The value is 0x400100 with type pointer-to-int.

Which of this is an lvalue? Well A *can* be an lvalue, because you
can use & on it to obtain it's address (0x400100), allowing you to
store another value in there:

A = 79;

But I don't think an lvalue is specifically the address of something. Here:

enum {C=12};

'C' is the name of a constant value '12'. There is no address, and
therefore it can't be an lvalue. The type I would guess is just int.


--
Bartc

== 3 of 6 ==
Date: Tues, Apr 6 2010 2:38 pm
From: Keith Thompson


Nicklas Karlsson <karlsson.nicklas@gmail.com> writes:
[...]
> Im not sure I follow, an rvalue is the value of an expression, its not
> an expression? While an lvalue is an expression?

Yes, given the way the C standard defines the terms.

> But an lvalue is an
> expression that does not evaluate to an rvalue?

No.

Keep in mind that the C standard doesn't generally use the term
"rvalue". The only two occurences of the term are in that footnote
and in the corresponding index entry. If you're discussing C, it's
best to avoid the term "rvalue" altogether.

If an lvalue (a kind of expression) appears in a context that requires
an lvalue, it doesn't yield a result in the ordinary sense; rather, it
serves to designate (or identify) the object that's required in that
context. If it appears on the LHS of an assignment operator, it
designates the object to which a value is to be assigned. If it
appears as the operand of a unary "&" operator, it designates the
object whose address is taken. And so forth.

If an lvalue appears in a context that *doesn't* require an lvalue, it
yields an ordinary value -- specifically, it yields the stored value
of the object that it designates.

Thus:

int x = 10;
int y = 20;
x = y;

In the assignment, both ``x'' and ''y'' are lvalues. Since ``x'' is
in a context that requires an lvalue, it identifies the object to be
written to (the previous value of that object, 10, is ignored). Since
''y'' is in a context that *doesn't* require an lvalue, it yields the
value (20) stored in the object that it designates (y).

(I'm using ``y'' to refer to the expression consisting of the
identifier y and just y to refer to the object. This isn't a standard
typographical convention, just the one I'm using here.)

> And since an lvalue is
> an expression it evaluates to something, what exactly does it evaluate
> to?

It depends on the context; see above.

> Something that has a designated object and has a type? I read that
> PDF and it said: "if an lvalue does not designate an object when it is
> evaluated..." so it is something that designates an object? Am I
> thinking wrong?

An lvalue is an expression that designates an object.

Actually, that's not *quite* accurate. Given:
int *ptr = NULL;
the expression *ptr is an lvalue, even though it doesn't happen to
refer to any object at run time. This is the subtlety that has
tripped up the authors of the standard in trying to define the term.
(I won't go into the gory details yet again unless you really want me
to.)

What the standard probably should say is "if an lvalue does not
designate an object when it is evaluated *in a context that requires
an lvalue*, the behavior is undefined. And the definition should say
something along the lines that an lvalue is an expression that
*potentially* designates an object.

Given:

int x = 42;
int *ptr;

the expressions ``x'' and` ``*ptr'' are both lvalues. ``x''
unconditionally designates an object. ``*ptr'' may or may not
designate an object, depending on the value currently stored in
ptr; this is where the potential for undefined behavior comes in.
``42'' cannot possibly designate an object and is not an lvalue,
so an attempt to use it in a context requiring an lvalue will be
flagged at compile time.

> And the expression does evaluate to an address?

No. Evaluating an lvalue in a context that requires an lvalue
identifies an object. It doesn't yield the object's address. It
could well be implemented by computing the object's address, but
consider this:
register int reg;
reg = 42;
The object reg has no address, but ``reg'' nevertheless designates
that object. The same applies to bit fields, which also have no
address.

> I read
> this: http://accu.org/index.php/journals/227 it sorta says "every
> expression yields either an lvalue or an rvalue and accordingly every
> expression is called either an lvalue or an rvalue expression." that
> is wrong, well it appears to be right now anyhow?

It "sorta says"? Actually, you quoted the exact words, but you
didn't quote the beginning of the sentence:

*In C++* every expression yields either an lvalue or an rvalue and
accordingly every expression is called either an lvalue or an
rvalue expression.

I think that C++ defines the terms differently than C does. For
information on C++, see elsewhere.

I mentioned that the C standard doesn't use the traditional meanings
of the terms. I'll summarize my understanding of what those
traditional meanings are.

In a very simple language without objects, each expression yields a
value when evaluated. ``2 + 2'' yields the value 4, for example.

Once you introduce objects, assuming you want to treat assignments as
expressions, there are two possible ways to evaluate an expression.
You can either evaluate it to determine its value (``2 + 2'' yields
4, ``x + 3'' yields 45 if you've previously stored the value 42 in
x) *or* you can evaluate it to determine what object it designates,
ignoring any value that might be stored in that object. Which of
these things happens depends on the context in which the expression
appears. Traditionally, the former is referred to as "evaluating
an expression for its rvalue", and the latter as "evaluating an
expression for its lvalue". An rvalue is just an ordinary value of
some type. An lvalue is something that, rather than being a *value*
of some type, identifies an *object* of some type. The traditional
terminology unifies these two things (having a value vs. identifying
an object) into the single concept of "value", divided into "rvalue"
and "lvalue". The names of course come from the contexts in which
they appear, the right side vs. the left side of an assignment.

Note that some expressions, such as ``2 + 2'' cannot be evaluated for
their lvalues. (In C terms, ``2 + 2'' is not an lvalue.)

The authors of the C standard chose to drop the concept of "rvalue"
(other than a brief mention in a footnote which matches the
traditional meaning) and redefine "lvalue" as a kind of expression
rather than as the result of evaluating such an expression.

I'm sorry this is so long; I didn't have time to make it shorter.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


== 4 of 6 ==
Date: Tues, Apr 6 2010 3:38 pm
From: Nicklas Karlsson


On Apr 6, 11:38 pm, Keith Thompson <ks...@mib.org> wrote:
> Nicklas Karlsson <karlsson.nick...@gmail.com> writes:
>
> [...]
>
> > Im not sure I follow, an rvalue is the value of an expression, its not
> > an expression? While an lvalue is an expression?
>
> Yes, given the way the C standard defines the terms.
>
> >                                                  But an lvalue is an
> > expression that does not evaluate to an rvalue?
>
> No.
>
> Keep in mind that the C standard doesn't generally use the term
> "rvalue".  The only two occurences of the term are in that footnote
> and in the corresponding index entry.  If you're discussing C, it's
> best to avoid the term "rvalue" altogether.
>
> If an lvalue (a kind of expression) appears in a context that requires
> an lvalue, it doesn't yield a result in the ordinary sense; rather, it
> serves to designate (or identify) the object that's required in that
> context.  If it appears on the LHS of an assignment operator, it
> designates the object to which a value is to be assigned.  If it
> appears as the operand of a unary "&" operator, it designates the
> object whose address is taken.  And so forth.
>
> If an lvalue appears in a context that *doesn't* require an lvalue, it
> yields an ordinary value -- specifically, it yields the stored value
> of the object that it designates.
>
> Thus:
>
>     int x = 10;
>     int y = 20;
>     x = y;
>
> In the assignment, both ``x'' and ''y'' are lvalues.  Since ``x'' is
> in a context that requires an lvalue, it identifies the object to be
> written to (the previous value of that object, 10, is ignored).  Since
> ''y'' is in a context that *doesn't* require an lvalue, it yields the
> value (20) stored in the object that it designates (y).
>
> (I'm using ``y'' to refer to the expression consisting of the
> identifier y and just y to refer to the object.  This isn't a standard
> typographical convention, just the one I'm using here.)
>
> >                                                 And since an lvalue is
> > an expression it evaluates to something, what exactly does it evaluate
> > to?
>
> It depends on the context; see above.
>
> >     Something that has a designated object and has a type? I read that
> > PDF and it said: "if an lvalue does not designate an object when it is
> > evaluated..." so it is something that designates an object? Am I
> > thinking wrong?
>
> An lvalue is an expression that designates an object.
>
> Actually, that's not *quite* accurate.  Given:
>     int *ptr = NULL;
> the expression *ptr is an lvalue, even though it doesn't happen to
> refer to any object at run time.  This is the subtlety that has
> tripped up the authors of the standard in trying to define the term.
> (I won't go into the gory details yet again unless you really want me
> to.)
>
> What the standard probably should say is "if an lvalue does not
> designate an object when it is evaluated *in a context that requires
> an lvalue*, the behavior is undefined.  And the definition should say
> something along the lines that an lvalue is an expression that
> *potentially* designates an object.
>
> Given:
>
>     int x = 42;
>     int *ptr;
>
> the expressions ``x'' and` ``*ptr'' are both lvalues.  ``x''
> unconditionally designates an object.  ``*ptr'' may or may not
> designate an object, depending on the value currently stored in
> ptr; this is where the potential for undefined behavior comes in.
> ``42'' cannot possibly designate an object and is not an lvalue,
> so an attempt to use it in a context requiring an lvalue will be
> flagged at compile time.
>
> >                 And the expression does evaluate to an address?
>
> No.  Evaluating an lvalue in a context that requires an lvalue
> identifies an object.  It doesn't yield the object's address.  It
> could well be implemented by computing the object's address, but
> consider this:
>     register int reg;
>     reg = 42;
> The object reg has no address, but ``reg'' nevertheless designates
> that object.  The same applies to bit fields, which also have no
> address.
>
> >                                                                 I read
> > this:http://accu.org/index.php/journals/227it sorta says "every
> > expression yields either an lvalue or an rvalue and accordingly every
> > expression is called either an lvalue or an rvalue expression." that
> > is wrong, well it appears to be right now anyhow?
>
> It "sorta says"?  Actually, you quoted the exact words, but you
> didn't quote the beginning of the sentence:
>
>     *In C++* every expression yields either an lvalue or an rvalue and
>     accordingly every expression is called either an lvalue or an
>     rvalue expression.
>
> I think that C++ defines the terms differently than C does.  For
> information on C++, see elsewhere.
>
> I mentioned that the C standard doesn't use the traditional meanings
> of the terms.  I'll summarize my understanding of what those
> traditional meanings are.
>
> In a very simple language without objects, each expression yields a
> value when evaluated.  ``2 + 2'' yields the value 4, for example.
>
> Once you introduce objects, assuming you want to treat assignments as
> expressions, there are two possible ways to evaluate an expression.
> You can either evaluate it to determine its value (``2 + 2'' yields
> 4, ``x + 3'' yields 45 if you've previously stored the value 42 in
> x) *or* you can evaluate it to determine what object it designates,
> ignoring any value that might be stored in that object.  Which of
> these things happens depends on the context in which the expression
> appears.  Traditionally, the former is referred to as "evaluating
> an expression for its rvalue", and the latter as "evaluating an
> expression for its lvalue".  An rvalue is just an ordinary value of
> some type.  An lvalue is something that, rather than being a *value*
> of some type, identifies an *object* of some type.  The traditional
> terminology unifies these two things (having a value vs. identifying
> an object) into the single concept of "value", divided into "rvalue"
> and "lvalue".  The names of course come from the contexts in which
> they appear, the right side vs. the left side of an assignment.
>
> Note that some expressions, such as ``2 + 2'' cannot be evaluated for
> their lvalues.  (In C terms, ``2 + 2'' is not an lvalue.)
>
> The authors of the C standard chose to drop the concept of "rvalue"
> (other than a brief mention in a footnote which matches the
> traditional meaning) and redefine "lvalue" as a kind of expression
> rather than as the result of evaluating such an expression.
>
> I'm sorry this is so long; I didn't have time to make it shorter.
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org  <http://www.ghoti.net/~kst>
> Nokia
> "We must do something.  This is something.  Therefore, we must do this."
>     -- Antony Jay and Jonathan Lynn, "Yes Minister"

Thanks for the reply guys!

So an lvalue does NOT evaluate in a traditional sense (yield a value)
but its being EVALUATED, so that the compiler can identify an object
and a size, the result of the evaluation specifies an object and a
type (and an object is a memory address right?) so if its on the left
side of assignenment it tells the compiler where to put the rvalue and
how much it can put, and if it appears on the right hand of assignment
it tells the compiler where to read the rvalue and how much to read?
Then you confuse me (:P) and say "and the latter as 'evaluating an
expression for its lvalue'", I thought we establised that the
expression itself was the lvalue?

In this: http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc05lvalue.htm
they call rvalues expressions too, but that is faulty (as the C-
standard says its a value of an expression), it may only apply to C++?
It also says: "When an lvalue appears in a context that requires an
rvalue, the lvalue is implicitly converted to an rvalue." that just
means that it starts to reads the rvalue at the address the lvalue
identifies? The lvalue is still evaluated right?

See I dont have a C-bot but a C++-bot and it shows precedence like
this ((*p) = 5); for *p = 5; and the (*p) must show that its being
evaluated right? But it shows i = 5; as (i = 5) but both are
expressions so I dont get why precedence differs?


== 5 of 6 ==
Date: Tues, Apr 6 2010 4:17 pm
From: Keith Thompson


Nicklas Karlsson <karlsson.nicklas@gmail.com> writes:
[...]
> Thanks for the reply guys!

When you post a followup, please trim any quoted material that isn't
necessary. In particular, please don't quote signatures.

> So an lvalue does NOT evaluate in a traditional sense (yield a value)
> but its being EVALUATED, so that the compiler can identify an object
> and a size,

Yes, but I wouldn't place so much emphasis on the size.

An lvalue (which is an expression) is of a particular type (and the
size is an attribute of that type). It identifies an object, which is
treated as being of that type. Usually that's going to be the
declared typethe object. If it's not (say, if there are pointer
conversions involved), then the type of the lvalue is what determines
the behavior.

A silly example:

int n;
*(unsigned int*)&n = 43;

Here n is declared to be of type int, but the lvalue
*(unsigned int*)&n
is of type unigsned int.

> the result of the evaluation specifies an object and a
> type (and an object is a memory address right?)

An object is, by definition, a "region of data storage in the
execution environment, the contents of which can represent values"
(C99 3.14). An object is not an address; an object (usually) *has* an
address.

> so if its on the left
> side of assignenment it tells the compiler where to put the rvalue and
> how much it can put,

It tells the compiler the identify and type of the object into which
the value is to be stored. Remember I suggested avoiding the term
"rvalue"; the value to be stored is the value resulting from the
evaluation of the RHS expression.

> and if it appears on the right hand of assignment
> it tells the compiler where to read the rvalue and how much to read?

If an lvalue appears as the RHS of an assignment, it's just evaluated,
yielding the value stored in the designated object.

> Then you confuse me (:P) and say "and the latter as 'evaluating an
> expression for its lvalue'", I thought we establised that the
> expression itself was the lvalue?

In C terms, yes. As I said, the C standard assigns a non-traditional
meaning to the term "lvalue". In C, the expression itself is the
lvalue.

> In this: http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc05lvalue.htm
> they call rvalues expressions too, but that is faulty (as the C-
> standard says its a value of an expression), it may only apply to C++?
> It also says: "When an lvalue appears in a context that requires an
> rvalue, the lvalue is implicitly converted to an rvalue." that just
> means that it starts to reads the rvalue at the address the lvalue
> identifies? The lvalue is still evaluated right?

You're asking about C++ in a C newsgroup. lvalue-to-rvalue conversion
is a C++ concept, not a C concept. C++ has its own set of newsgroups
(and FAQs, which you should check before posting).

(I just checked the C++ standard. C++ definitely defines "rvalue"
differently than C does. Its definition of "lvalue' may or may not
be consistent with C's.)

> See I dont have a C-bot but a C++-bot and it shows precedence like
> this ((*p) = 5); for *p = 5; and the (*p) must show that its being
> evaluated right? But it shows i = 5; as (i = 5) but both are
> expressions so I dont get why precedence differs?

Precedence has nothing to do with it.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


== 6 of 6 ==
Date: Tues, Apr 6 2010 4:56 pm
From: Nicklas Karlsson


> You're asking about C++ in a C newsgroup.  lvalue-to-rvalue conversion
> is a C++ concept, not a C concept.  C++ has its own set of newsgroups
> (and FAQs, which you should check before posting).

Sorry, from the looks of it I thought that link was talking about both
C and C++


So if an identifier is declared and used as an lvalue, the compiler
knows that lvalues type because its the type which the the identifier
is declared with, and if its pointer conversion the compiler knows the
lvalues type from context (for example *(int*)0x0 will be an lvalue of
type "int"), so is it the expression itself that has a type or does
that expression evaluate so that the compiler knows its type (and
therefor size), like "this lvalue evaluated, the object it designated
starts at address ****** and the type of that object is"?

An object is, and I quote: "a region of data storage in the execution
environment, the contents of which can represent values" so its an
entire region of memory (usally), which is usally identified by a
memory address?

"If an lvalue appears as the RHS of an assignment, it's just
evaluated, yielding the value stored in the designated object." so
there is no conversion going on? it evaluates the lvalue and reads the
data of the object that lvalue identified?

"Precedence has nothing to do with it."
I thought it was order of evaluation, and I'm just wondering why one
lvalue (indirection) is different from an identifer as an lvalue in
terms of evaluation, but its probably off topic since its a C++ bot
and what I linked earlier about C++ lvalues seem different than C's

"knows what type is going to be used for that object"

==============================================================================
TOPIC: Computing a*b/c without overflow in the preprocessor
http://groups.google.com/group/comp.lang.c/t/1049c69de2e8ea27?hl=en
==============================================================================

== 1 of 1 ==
Date: Tues, Apr 6 2010 2:15 pm
From: Francois Grieu


Mark Piffer wrote:
> On 31 Mrz., 22:41, Francois Grieu <fgr...@gmail.com> wrote:
>> James Dow Allen wrote:
>>> On Mar 30, 1:42 pm, Francois Grieu <fgr...@gmail.com> wrote:
>>>> James Dow Allen wrote:
>>>>> [bad idea]
>>>> Because that's not possible in a preprocessor expression?
>>>>> [another bad idea]
>>>> That works in the preprocessor, with a fixed depth. But it generates
>>>> huge expressions, and won't cut it when c is coprime with a and b.
>>> I detected some of my own stupidities after clicking Send,
>>> but you beat me to the debunker. :-)
>>> Hoping to make amends, let me outline another solution that
>>> *might* work.
>>> On Mar 30, 4:52 am, Francois Grieu <fgr...@gmail.com> wrote:
>>>> I want to devise a C89 preprocessor macro MULDIV(a,b,c)
>>>> ... a, b, c, a*b/c are all in range [1..2000000000].
>>>> ...
>>>> I could live with a slightly inaccurate result,
>>>> provided the relative error is always at most 1/10000.
>>> You've got 31-bit inputs, but only need 14-bit precision.
>> Yes. I could lower precision to 1/8192 (13 bits).
>>
>>> Create macro to give crude estimate of log(x); shift
>>> a and b right enough so that log(a) + log(b) < 32;
>>> do the arithmetic; shift back at the end.
>>> This might be very cumbersome (various cases depending
>>> on log(a)) but should avoid the other difficulties.
>> I fear it does not give the required precision when the result is small; in my mind 65535*65535/858967245 should give exactly 5 (either 4 or 6 is off by 20%) and 65534*65535/858967245 should give exactly 4 (either 3 or 5 is off by 25%).
>>
>>> As for the preprocessor-usable log(x) estimator,
>>> one of two of the methods under
>>> "Finding integer log base 2 of an integer" at
>>> http://graphics.stanford.edu/~seander/bithacks.html
>>> might work.
>> I fear these expand to huge things. The least expansion that I have found so far is the straightforward (not tested)
>> #define LOG2(x) (30-((x)<2)-((x)<4)-((x)<8)-((x)<16)\
>> -((x)<32)-((x)<64)-((x)<128)-((x)<256)-((x)<512)-((x)<1024)\
>> -((x)<2048)-((x)<4096)-((x)<8192)-!((x)>>14)-!((x)>>15)\
>> -!((x)>>16)-!((x)>>17)-!((x)>>18)-!((x)>>19)-!((x)>>20)\
>> -!((x)>>21)-!((x)>>22)-!((x)>>23)-!((x)>>24)-!((x)>>25)\
>> -!((x)>>26)-!((x)>>27)-!((x)>>28)-!((x)>>29)-!((x)>>30))
>>
>> This macro is needed several times, x itself can be an expression, and thus the whole thing will expand terribly.
>>
>> Fran ois Grieu- Zitierten Text ausblenden -
>>
>
> Francois,
>
> if you don't dare to throw awkwardly big and complex expressions at
> the preprocessor you could as well stop right now. There simply is no
> way to have it nice and easy with a so-so functional expansion
> language.

Looks like it. On the other hand, a little math can help immensely (in fact my problem is 99% solved with the modular reduction trick in my original post).

> Returning to your original problem: why not resorting to true 64 Bit
> math? The expression of the division will be tedious (and for sure it
> will blow an implementation-limit-wise exactly conforming preprocessor
> to smithereens) but it should be doable.

> #define PP_CMP_U64(a,b) PP_CMP_U64_(a,b)
> #define PP_CMP_U64_(a_hi,a_lo,b_hi,b_lo) (((a_hi)>(b_hi)) ||
> ((a_hi)==(b_hi))&&((a_lo)>(b_lo)))
> #define PP_U64(a_hi,a_lo) (a_hi),(a_lo)
> #define PP_ADD_U64(a,b) PP_ADD_U64_((a),(b))
> #define PP_ADD_U64_(a_hi,a_lo,b_hi,b_lo) ((a_hi)+(b_hi)+((a_lo)+
> (b_lo)<(a_lo))),((a_lo)+(b_lo))
>
> #define A PP_U64(0UL,-1UL)
> #define B PP_U64(0UL,1UL)
>
> #if PP_CMP_U64(PP_ADD_U64(A,B),A)
> # error "A+B > A, ok!"
>

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate