comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en
comp.lang.c++@googlegroups.com
Today's topics:
* Address one past the end of array - is this syntax a valid C++? - 4 messages,
3 authors
http://groups.google.com/group/comp.lang.c++/t/3660f2b84a4f1cb3?hl=en
* Choosing the right epsilon for comparing doubles - 10 messages, 5 authors
http://groups.google.com/group/comp.lang.c++/t/5f5b1d64b66b5096?hl=en
* Meaning of ~0 - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/49b86d4e311b7a5f?hl=en
* question regarding the shared_ptr use_count - 6 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/236ca0a4278d1ba0?hl=en
* Boost - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/81738d66827a11c8?hl=en
* template friend with local classes ? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/1013c4946db48f70?hl=en
* Functor with recursive call - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/7c8534b6a9ab8b48?hl=en
==============================================================================
TOPIC: Address one past the end of array - is this syntax a valid C++?
http://groups.google.com/group/comp.lang.c++/t/3660f2b84a4f1cb3?hl=en
==============================================================================
== 1 of 4 ==
Date: Sun, Feb 2 2014 6:36 am
From: Dombo
Op 01-Feb-14 23:36, Victor Bazarov schreef:
> On 2/1/2014 12:23 PM, Peter wrote:
>> Assume we have an array:
>>
>> int arr[5];
>>
>> It's legal to refer to address arr + 5, but, of course, illegal to
>> refer to element arr[5] as it's not part of the array. However, arr +
>> n is equivalent to &arr[n]. My question is: does this equivalence
>> also hold for an edge case of n = 5 (or, generally, n equal to number
>> of elements of array)?
>>
>> While there's nothing wrong with arr + 5, &arr[5] looks highly
>> suspicious: it looks like in the first step arr[5] is evaluated
>> (which introduces an undefined behaviour) which would mean the
>> expression as a whole is undefined. Does the equivalence still hold
>> in this special case?
>
> I would not be surprised at the validity of this after I've learned that
> initializing a reference by dereferencing a null pointer is now legal.
> *nullptr creates a special kind of reference, and the only useful
> operation you can do with it is to take its address, which in turn
> should give you null, as I understand it. So, using the same logic, the
> expression a[n] is the same as *(a+n), which is to give you a reference
> to a non-existing element (one beyond the last in the array) and with
> that reference the only valid operation is to take its address.
> According to the precedence rules, &arr[5] is evaluated as &(*(arr+5)),
> which is OK (if you subscribe to the invalid reference idea and the
> validity of applying the 'address of' operator to it).
I'm not sure this is the case; according to the C++ 11 draft standard
(N3337): "Note: std::nullptr_t is a distinct type that is neither a
pointer type nor a pointer to member type; rather, a prvalue of this
type is a null pointer constant and can be converted to a null pointer
value or null member pointer value.". I.e. since nullptr is not a
pointer type the fact that you can legally dereference it (which
surprised me a bit, but I suppose there is a good reason for it),
doesn't necessarily mean that it is also legal to dereference a pointer
referencing a non-existing element.
== 2 of 4 ==
Date: Sun, Feb 2 2014 8:47 am
From: Mr Flibble
On 02/02/2014 12:39, bblaz wrote:
> On 02/02/14 00:33, Mr Flibble wrote:
>> On 01/02/2014 22:36, Victor Bazarov wrote:
>>> On 2/1/2014 12:23 PM, Peter wrote:
>>>> Assume we have an array:
>>>>
>>>> int arr[5];
>>>>
>>>> It's legal to refer to address arr + 5, but, of course, illegal to
>>>> refer to element arr[5] as it's not part of the array. However, arr +
>>>> n is equivalent to &arr[n]. My question is: does this equivalence
>>>> also hold for an edge case of n = 5 (or, generally, n equal to number
>>>> of elements of array)?
>>>>
>>>> While there's nothing wrong with arr + 5, &arr[5] looks highly
>>>> suspicious: it looks like in the first step arr[5] is evaluated
>>>> (which introduces an undefined behaviour) which would mean the
>>>> expression as a whole is undefined. Does the equivalence still hold
>>>> in this special case?
>>>
>>> I would not be surprised at the validity of this after I've learned that
>>> initializing a reference by dereferencing a null pointer is now legal.
>>> *nullptr creates a special kind of reference, and the only useful
>>> operation you can do with it is to take its address, which in turn
>>> should give you null, as I understand it. So, using the same logic, the
>>> expression a[n] is the same as *(a+n), which is to give you a reference
>>> to a non-existing element (one beyond the last in the array) and with
>>> that reference the only valid operation is to take its address.
>>> According to the precedence rules, &arr[5] is evaluated as &(*(arr+5)),
>>> which is OK (if you subscribe to the invalid reference idea and the
>>> validity of applying the 'address of' operator to it).
>>
>> Bullshit mate; dereferencing null pointers is UB.
>>
>> /Flibble
>
> Not always true.
More bullshit. It is always true mate; dereferencing null pointers is UB.
8.3.2/5
"A reference shall be initialized to refer to a valid object
or function. [ Note: in particular, a null reference cannot exist in a
well-defined program, because the only
way to create such a reference would be to bind it to the "object"
obtained by dereferencing a null pointer,
which causes undefined behavior. As described in 9.6, a reference cannot
be bound directly to a bit-field.
--end note ]"
[snipped unrelated Standard quotes]
/Flibble
== 3 of 4 ==
Date: Sun, Feb 2 2014 9:43 am
From: bblaz
On 02/02/14 17:47, Mr Flibble wrote:
> On 02/02/2014 12:39, bblaz wrote:
>> On 02/02/14 00:33, Mr Flibble wrote:
>>> On 01/02/2014 22:36, Victor Bazarov wrote:
>>>> On 2/1/2014 12:23 PM, Peter wrote:
>>>>> Assume we have an array:
>>>>>
>>>>> int arr[5];
>>>>>
>>>>> It's legal to refer to address arr + 5, but, of course, illegal to
>>>>> refer to element arr[5] as it's not part of the array. However, arr +
>>>>> n is equivalent to &arr[n]. My question is: does this equivalence
>>>>> also hold for an edge case of n = 5 (or, generally, n equal to number
>>>>> of elements of array)?
>>>>>
>>>>> While there's nothing wrong with arr + 5, &arr[5] looks highly
>>>>> suspicious: it looks like in the first step arr[5] is evaluated
>>>>> (which introduces an undefined behaviour) which would mean the
>>>>> expression as a whole is undefined. Does the equivalence still hold
>>>>> in this special case?
>>>>
>>>> I would not be surprised at the validity of this after I've learned
>>>> that
>>>> initializing a reference by dereferencing a null pointer is now legal.
>>>> *nullptr creates a special kind of reference, and the only useful
>>>> operation you can do with it is to take its address, which in turn
>>>> should give you null, as I understand it. So, using the same logic,
>>>> the
>>>> expression a[n] is the same as *(a+n), which is to give you a reference
>>>> to a non-existing element (one beyond the last in the array) and with
>>>> that reference the only valid operation is to take its address.
>>>> According to the precedence rules, &arr[5] is evaluated as &(*(arr+5)),
>>>> which is OK (if you subscribe to the invalid reference idea and the
>>>> validity of applying the 'address of' operator to it).
>>>
>>> Bullshit mate; dereferencing null pointers is UB.
>>>
>>> /Flibble
>>
>> Not always true.
>
> More bullshit. It is always true mate; dereferencing null pointers is UB.
>
> 8.3.2/5
>
> "A reference shall be initialized to refer to a valid object
> or function. [ Note: in particular, a null reference cannot exist in a
> well-defined program, because the only
> way to create such a reference would be to bind it to the "object"
> obtained by dereferencing a null pointer,
> which causes undefined behavior. As described in 9.6, a reference cannot
> be bound directly to a bit-field.
> --end note ]"
>
> [snipped unrelated Standard quotes]
>
> /Flibble
& is an unary operator & not a reference type. I think your quote is
irrelevant in this case.
blaz
== 4 of 4 ==
Date: Sun, Feb 2 2014 9:45 am
From: bblaz
On 02/02/14 19:43, bblaz wrote:
> On 02/02/14 17:47, Mr Flibble wrote:
>> On 02/02/2014 12:39, bblaz wrote:
>>> On 02/02/14 00:33, Mr Flibble wrote:
>>>> On 01/02/2014 22:36, Victor Bazarov wrote:
>>>>> On 2/1/2014 12:23 PM, Peter wrote:
>>>>>> Assume we have an array:
>>>>>>
>>>>>> int arr[5];
>>>>>>
>>>>>> It's legal to refer to address arr + 5, but, of course, illegal to
>>>>>> refer to element arr[5] as it's not part of the array. However, arr +
>>>>>> n is equivalent to &arr[n]. My question is: does this equivalence
>>>>>> also hold for an edge case of n = 5 (or, generally, n equal to number
>>>>>> of elements of array)?
>>>>>>
>>>>>> While there's nothing wrong with arr + 5, &arr[5] looks highly
>>>>>> suspicious: it looks like in the first step arr[5] is evaluated
>>>>>> (which introduces an undefined behaviour) which would mean the
>>>>>> expression as a whole is undefined. Does the equivalence still hold
>>>>>> in this special case?
>>>>>
>>>>> I would not be surprised at the validity of this after I've learned
>>>>> that
>>>>> initializing a reference by dereferencing a null pointer is now legal.
>>>>> *nullptr creates a special kind of reference, and the only useful
>>>>> operation you can do with it is to take its address, which in turn
>>>>> should give you null, as I understand it. So, using the same logic,
>>>>> the
>>>>> expression a[n] is the same as *(a+n), which is to give you a
>>>>> reference
>>>>> to a non-existing element (one beyond the last in the array) and with
>>>>> that reference the only valid operation is to take its address.
>>>>> According to the precedence rules, &arr[5] is evaluated as
>>>>> &(*(arr+5)),
>>>>> which is OK (if you subscribe to the invalid reference idea and the
>>>>> validity of applying the 'address of' operator to it).
>>>>
>>>> Bullshit mate; dereferencing null pointers is UB.
>>>>
>>>> /Flibble
>>>
>>> Not always true.
>>
>> More bullshit. It is always true mate; dereferencing null pointers is UB.
>>
>> 8.3.2/5
>>
>> "A reference shall be initialized to refer to a valid object
>> or function. [ Note: in particular, a null reference cannot exist in a
>> well-defined program, because the only
>> way to create such a reference would be to bind it to the "object"
>> obtained by dereferencing a null pointer,
>> which causes undefined behavior. As described in 9.6, a reference cannot
>> be bound directly to a bit-field.
>> --end note ]"
>>
>> [snipped unrelated Standard quotes]
>>
>> /Flibble
>
> & is an unary operator & not a reference type. I think your quote is
> irrelevant in this case.
>
> blaz
To be clear, i was refering to the op.
==============================================================================
TOPIC: Choosing the right epsilon for comparing doubles
http://groups.google.com/group/comp.lang.c++/t/5f5b1d64b66b5096?hl=en
==============================================================================
== 1 of 10 ==
Date: Sun, Feb 2 2014 8:35 am
From: walkietalkie74
Hi all,
Sorry if this question has been already asked in the past (I bet so). I would appreciate if you could point me in the right direction.
I do not generally compare doubles because I am well aware of the round-off errors that make such a comparison meaningless.
However, I am trying to write my program in a test-driven way, so I'd like to write a tester that checks that the result of a specific calculation is actually zero.
My code is the one below. It's calculating a straight line equation based on a point and a vector (in space, a straight line is the intersection of two planes, hence the getPlane1() and getPlane2()), and is checking whether the obtained equation is correct by calculating arbitrary points that are supposed to be on the same straight line, and checking whether their coordinates solve the plane equations:
bool GeometryTester::runTests() {
Point p(2, -2, 1);
Vector v(2, 4, 2);
StraightLine straightLine = Geometry::getStraightLine(p, v);
bool result = true;
for (double scalar = -10.0; scalar <= 10.0; scalar += 0.11131719) {
Point calcPoint = Geometry::getPoint(p, v, scalar);
double s1 = straightLine.getPlane1().solve(calcPoint.getX(),
calcPoint.getY(),
calcPoint.getZ());
double s2 = straightLine.getPlane2().solve(calcPoint.getX(),
calcPoint.getY(),
calcPoint.getZ());
result = result &&
MathComparer::equalsZero(s1);
result = result &&
MathComparer::equalsZero(s2);
}
return result;
}
For now, in MathComparer::equalsZero(), I am using a (wrong - I know) direct == comparison between the argument passed in and 0.0, but I'd like to replace it with the appropriate comparison using an epsilon.
Am I correct in thinking that the epsilon should actually be chosen depending on the current calculation and the accuracy I am expecting from it?
I can see, for example, that the solve() method most of the times returns 0.0 but at times something like 6e-12 (which is absolutely sensible, given the imprecise nature of floating-pint types).
Would it be sensible to pass in an arbitrary epsilon to the equalsZero() function?
I have seen examples of usage of std::numerics<double>::epsilon but I am not sure how it should be used in my case...
Can you help me understand this stuff better?
Thanks!
== 2 of 10 ==
Date: Sun, Feb 2 2014 1:15 pm
From: Richard Damon
On 2/2/14, 11:35 AM, walkietalkie74 wrote:
> Hi all,
>
> Sorry if this question has been already asked in the past (I bet so).
> I would appreciate if you could point me in the right direction.
>
> I do not generally compare doubles because I am well aware of the
> round-off errors that make such a comparison meaningless.
>
> However, I am trying to write my program in a test-driven way, so I'd
> like to write a tester that checks that the result of a specific
> calculation is actually zero.
...
>
> Am I correct in thinking that the epsilon should actually be chosen
> depending on the current calculation and the accuracy I am expecting
> from it?
>
> I can see, for example, that the solve() method most of the times
> returns 0.0 but at times something like 6e-12 (which is absolutely
> sensible, given the imprecise nature of floating-pint types).
>
> Would it be sensible to pass in an arbitrary epsilon to the
> equalsZero() function?
>
> I have seen examples of usage of std::numerics<double>::epsilon but I
> am not sure how it should be used in my case...
>
> Can you help me understand this stuff better?
>
> Thanks!
>
Yes, you are correct that "How close to zero is ok" is a question that
is VERY much dependent on the problem at hand. There are ways to analyze
the computation to see how much error would be "expected", to help you
set the bounds.
The other alternative would be to replace the floating point either with
an "exact math" number class (assuming the answers are expressible with
that or a number type that keeps track of possible error (either as an
interval of possible values, or as a estimated value and error bound).
== 3 of 10 ==
Date: Sun, Feb 2 2014 1:42 pm
From: Jax
walkietalkie74 <a.laforgia@gmail.com> wrote in
news:60d97607-ea5c-4001-96fc-6e48f0211d65@googlegroups.com:
> Hi all,
>
> Sorry if this question has been already asked in the past (I bet so). I
> would appreciate if you could point me in the right direction.
>
> I do not generally compare doubles because I am well aware of the
> round-off errors that make such a comparison meaningless.
>
> However, I am trying to write my program in a test-driven way, so I'd
> like to write a tester that checks that the result of a specific
> calculation is actually zero.
>
> My code is the one below. It's calculating a straight line equation
> based on a point and a vector (in space, a straight line is the
> intersection of two planes, hence the getPlane1() and getPlane2()), and
> is checking whether the obtained equation is correct by calculating
> arbitrary points that are supposed to be on the same straight line, and
> checking whether their coordinates solve the plane equations:
>
> bool GeometryTester::runTests() {
>
> Point p(2, -2, 1);
> Vector v(2, 4, 2);
> StraightLine straightLine = Geometry::getStraightLine(p, v);
>
> bool result = true;
>
> for (double scalar = -10.0; scalar <= 10.0; scalar += 0.11131719) {
> Point calcPoint = Geometry::getPoint(p, v, scalar);
>
> double s1 = straightLine.getPlane1().solve(calcPoint.getX(),
> calcPoint.getY(),
> calcPoint.getZ());
>
> double s2 = straightLine.getPlane2().solve(calcPoint.getX(),
> calcPoint.getY(),
> calcPoint.getZ());
>
> result = result &&
> MathComparer::equalsZero(s1);
>
> result = result &&
> MathComparer::equalsZero(s2);
> }
>
> return result;
> }
>
> For now, in MathComparer::equalsZero(), I am using a (wrong - I know)
> direct == comparison between the argument passed in and 0.0, but I'd
> like to replace it with the appropriate comparison using an epsilon.
>
> Am I correct in thinking that the epsilon should actually be chosen
> depending on the current calculation and the accuracy I am expecting
> from it?
>
> I can see, for example, that the solve() method most of the times
> returns 0.0 but at times something like 6e-12 (which is absolutely
> sensible, given the imprecise nature of floating-pint types).
>
> Would it be sensible to pass in an arbitrary epsilon to the equalsZero()
> function?
>
> I have seen examples of usage of std::numerics<double>::epsilon but I am
> not sure how it should be used in my case...
>
> Can you help me understand this stuff better?
>
> Thanks!
Walkietalkie as I'm sure you know there's more than one pair of planes
which can describe a given line..... so are there some special constraints
on the 2 planes you obtain which define the straight line? Just wondering.
Anyways you may want to consider always choosing the error (epsilon) to be
a few orders of magnitude greater than the specified inaccuracy of your
floating-point hardware. Alternatively, and I prefer this, epsilon could
be based on the magnitude of the numbers you are comparing rather than an
absolute constant.
--
Jax :)
== 4 of 10 ==
Date: Sun, Feb 2 2014 1:42 pm
From: Paavo Helde
walkietalkie74 <a.laforgia@gmail.com> wrote in
news:60d97607-ea5c-4001-96fc-6e48f0211d65@googlegroups.com:
> Hi all,
>
> Sorry if this question has been already asked in the past (I bet so).
> I would appreciate if you could point me in the right direction.
>
> I do not generally compare doubles because I am well aware of the
> round-off errors that make such a comparison meaningless.
>
> However, I am trying to write my program in a test-driven way, so I'd
> like to write a tester that checks that the result of a specific
> calculation is actually zero.
[...]
> For now, in MathComparer::equalsZero(), I am using a (wrong - I know)
> direct == comparison between the argument passed in and 0.0, but I'd
> like to replace it with the appropriate comparison using an epsilon.
>
> Am I correct in thinking that the epsilon should actually be chosen
> depending on the current calculation and the accuracy I am expecting
> from it?
Yes. As a trivial example, adding-subtracting an unbounded amount of
floating-point numbers can result in arbitrily large shifts from the
correct value.
However, most probably your algorithm has a limited number of floating-
point operations, so it ought to be possible to calculate the maximum
possible error. Alas, finding this can be well more complicated than the
original algorithm so it seems an overkill for a test function (you might
need to write a test for the test, etc). Probably the best approach is to
use some kind of epsilon estimated by gut feeling, but not totally
arbitrary.
>
> I can see, for example, that the solve() method most of the times
> returns 0.0 but at times something like 6e-12 (which is absolutely
> sensible, given the imprecise nature of floating-pint types).
6e-12 seems actually pretty big error unless the numbers in your tests
themselves are pretty large. The zero which is output from your test
function is most probably the result of subtracting two large numbers.
You should actually compare the relative difference of those numbers,
e.g. divide them by each other and if the result differs from 1.0 more
than a few epsilons (std::numeric_limits<double>::epsilon()) then your
algorithm might be either wrong or numerically unstable (the latter is
worse). The exact value of "few" above would be based on gut feeling ;-)
hth
Paavo
== 5 of 10 ==
Date: Sun, Feb 2 2014 2:40 pm
From: walkietalkie74
On Sunday, 2 February 2014 21:42:39 UTC, Jax wrote:
> Walkietalkie as I'm sure you know there's more than one pair of planes
> which can describe a given line..... so are there some special constraints
> on the 2 planes you obtain which define the straight line? Just wondering.
Hi Jax, thanks for your answer.
Yes, I know that there can be infinite pairs of planes which can describe a given line. This is the actual algorithm used in the method that builds the equations of the planes, given a point and a vector:
StraightLine Geometry::getStraightLine(const Point& p, const Vector& v) {
StraightLine straightLine;
double vx = v.getvx();
double vy = v.getvy();
double vz = v.getvz();
double xp = p.getX();
double yp = p.getY();
double zp = p.getZ();
straightLine.setPlane1(Plane(vy, -vx, 0, vx*yp - vy*xp));
straightLine.setPlane2(Plane(0, vz, -vy, vy*zp - vz*yp));
return straightLine;
}
Do you see any errors?
I used the GeometryTester class in my previous post to test that the equations are correct. Almost all the points that I calculate are solutions for the equations, with the exceptions of a few for which the solve() functions returns something like 0.000000000006....(which should be an approximation of zero - though I agree that it's quite a big error).
> Anyways you may want to consider always choosing the error (epsilon) to be
> a few orders of magnitude greater than the specified inaccuracy of your
> floating-point hardware. Alternatively, and I prefer this, epsilon could
> be based on the magnitude of the numbers you are comparing rather than an
> absolute constant.
Thanks. I have already discarded the idea of an absolute constant. I am aware of the existence of std::numerics<double>::epsilon and I've found a few examples around showing how to relate it to the magnitude of the numbers involved in the calculations.
Someone suggested to use it the following way:
a and b are "equal" if:
std::abs(a - b) <= std::abs(a) * std::numeric_limits<double>::epsilon
It seems using the same algorithm shown in section 4.2.2 of The Art of Computer Programming (D. Knuth), but it doesn't seem to work.
== 6 of 10 ==
Date: Sun, Feb 2 2014 2:57 pm
From: walkietalkie74
On Sunday, 2 February 2014 21:42:39 UTC, Paavo Helde wrote:
> However, most probably your algorithm has a limited number of floating-
> point operations, so it ought to be possible to calculate the maximum
> possible error. Alas, finding this can be well more complicated than the
> original algorithm so it seems an overkill for a test function (you might
> need to write a test for the test, etc). Probably the best approach is to
> use some kind of epsilon estimated by gut feeling, but not totally
> arbitrary.
Thanks for your answer. The problem with choosing an epsilon dictated by gut feeling is that it would make the tester class necessarily unreliable. I wouldn't be 100% sure that the epsilon would be correct in all circumstances, using any numbers. If a new developer adds a test case which fails, I have no way to figure out whether it's because of the wrong epsilon chosen or the new test condition itself...
> 6e-12 seems actually pretty big error unless the numbers in your tests
> themselves are pretty large. The zero which is output from your test
> function is most probably the result of subtracting two large numbers.
> You should actually compare the relative difference of those numbers,
> e.g. divide them by each other and if the result differs from 1.0 more
> than a few epsilons (std::numeric_limits<double>::epsilon()) then your
> algorithm might be either wrong or numerically unstable (the latter is
> worse). The exact value of "few" above would be based on gut feeling ;-)
Thanks for the suggestions. Really precious. I am afraid you're right. That difference seems quite a big error to me as well. I might well be doing what you say, because I've analysed the values at the intermediate steps of the algorithm and, for example, I've got something like the following:
38.398935600000016 -
3.3989356000000184 -
35
I will change the algorithm and follow your suggestions. Thanks!
== 7 of 10 ==
Date: Sun, Feb 2 2014 3:15 pm
From: walkietalkie74
On Sunday, 2 February 2014 21:15:49 UTC, Richard Damon wrote:
> The other alternative would be to replace the floating point either with
>
> an "exact math" number class
Thanks. That's another option I'd thought about.
I will google it and see if I can find any libraries.
== 8 of 10 ==
Date: Sun, Feb 2 2014 3:26 pm
From: ram@zedat.fu-berlin.de (Stefan Ram)
walkietalkie74 <a.laforgia@gmail.com> writes:
>a straight line is the intersection of two planes
A floating point number, like say, 10000.1, has an IEEE
hexadecimal representation, here: 0x1.3880ccccccccdp13, for
example. This actually represents a whole range of numbers
from 0x1.3880ccccccccc8p13 to 0x1.3880ccccccccd7p13 or
something like that.
This error of the plane parameters gives an error
(uncertainity) of the planes and of the line parameters. The
points of the line have to be points of the plane within the
limits of those errors. The details of error propagation
(propagation of distributions) are a standard subject of
numerical mathematics, I believe.
And strictly for every triple of a line and two planes,
we do not get a yes/no-answer but a probability that it
is correct.
But for any plane-like object in the physical world, we
cannot measure its parameters up to 15 digits, so the
measurement error usually exceeds this IEEE represenation
error. Possibly, this larger error also has to be taken
into consideration.
== 9 of 10 ==
Date: Sun, Feb 2 2014 3:45 pm
From: walkietalkie74
On Sunday, 2 February 2014 23:26:54 UTC, Stefan Ram wrote:
> This error of the plane parameters gives an error
>
> (uncertainity) of the planes and of the line parameters.
Hi Stefan. Thanks. Yes, I know that the floating point values are inherently imprecise and that any calculation with them can propagate errors. I wouldn't normally compare two doubles for equality. This necessity arises from the fact that I need to write a tester class. My three-dimensional objects will eventually be projected and displayed, so I am not really interested in having a perfect accuracy. I will try to rearrange the algorithm.
== 10 of 10 ==
Date: Sun, Feb 2 2014 4:23 pm
From: Richard Damon
On 2/2/14, 6:45 PM, walkietalkie74 wrote:
> On Sunday, 2 February 2014 23:26:54 UTC, Stefan Ram wrote:
>
>> This error of the plane parameters gives an error
>>
>> (uncertainity) of the planes and of the line parameters.
>
> Hi Stefan. Thanks. Yes, I know that the floating point values are
> inherently imprecise and that any calculation with them can propagate
> errors. I wouldn't normally compare two doubles for equality. This
> necessity arises from the fact that I need to write a tester class.
> My three-dimensional objects will eventually be projected and
> displayed, so I am not really interested in having a perfect
> accuracy. I will try to rearrange the algorithm.
>
One question, is how good does the results NEED to be? You really only
need to check that it is that accurate.
Another way to judge, if this error term corresponds to a distance, then
one reasonable way to set allowable error is reasonable epsilon based on
the magnitude of the input points.
==============================================================================
TOPIC: Meaning of ~0
http://groups.google.com/group/comp.lang.c++/t/49b86d4e311b7a5f?hl=en
==============================================================================
== 1 of 1 ==
Date: Sun, Feb 2 2014 12:02 pm
From: Paavo Helde
Old Wolf <oldwolf@inspire.net.nz> wrote in news:1022b30a-f150-48bf-99b8-
19319709d023@googlegroups.com:
> I'm sure this would have been asked before, but Google can't
> cope with searching for tilde, so...
>
> What does ~0 evaluate to?
>
> N2521 just says "The operand of ~ shall have integral or
> enumeration type; the result is the one's complement of
> its operand." without any further explanation.
>
> Does it mean the value whose representation is all-bits-1 ?
> What if this is a trap representation?
0 is a signed int value. Bitwise operations depend on the representation
of signed types, which are implementation-specific, so not very reliable.
Also, if you assign the result to a value of potentially larger type
(e.g. unsigned long), it may fail to initialize higher bits. Using ~0U, ~
0UL, ~0ULL would be better.
Actually there is a standard idiom to obtain an unsigned value of any
type with all bits set, namely by converting -1 to this type, e.g.
unsigned long x = -1;
This is guaranteed to work as the C++ standard specifies such conversions
as modulo 2^n, meaning you get an unsigned value of 2^n-1, which means
all bits set. However, this it not very intuitive so may confuse novices.
hth
==============================================================================
TOPIC: question regarding the shared_ptr use_count
http://groups.google.com/group/comp.lang.c++/t/236ca0a4278d1ba0?hl=en
==============================================================================
== 1 of 6 ==
Date: Sun, Feb 2 2014 5:12 pm
From: somenath
I am not able to understand the behavior of the following program
#include <iostream>
#include<memory>
#include<string>
using namespace std;
int main() {
auto p1 = make_shared<string> (10,'S');
cout<<"p1 use_count = "<<p1.use_count()<<endl;
shared_ptr<string> p2(new string()) ;
p1 = p2;
cout<<"p2 use_count = "<<p2.use_count()<<endl;
cout<<"second p1 use_count = "<<p1.use_count()<<endl;
return 0;
}
Output
++++++++++++++++
p1 use_count = 1
p2 use_count = 2
second p1 use_count = 2
I can understand the first two print. At beginning p1 points to one string so the reference count is 1.
When the statement p1=p2; executes p2's reference count gets incremented to 2 but at the same time I was expecting that p1's reference count to be decremented by 1 as p1 would be pointing to p2 now.
Please let me know where my understanding is going wrong?
== 2 of 6 ==
Date: Sun, Feb 2 2014 5:23 pm
From: Ian Collins
somenath wrote:
> I am not able to understand the behavior of the following program
>
> #include <iostream>
> #include<memory>
> #include<string>
> using namespace std;
>
> int main() {
> auto p1 = make_shared<string> (10,'S');
> cout<<"p1 use_count = "<<p1.use_count()<<endl;
> shared_ptr<string> p2(new string()) ;
> p1 = p2;
> cout<<"p2 use_count = "<<p2.use_count()<<endl;
> cout<<"second p1 use_count = "<<p1.use_count()<<endl;
> return 0;
> }
> Output
> ++++++++++++++++
> p1 use_count = 1
> p2 use_count = 2
> second p1 use_count = 2
>
> I can understand the first two print. At beginning p1 points to one
> string so the reference count is 1. When the statement p1=p2;
> executes p2's reference count gets incremented to 2 but at the same
> time I was expecting that p1's reference count to be decremented by 1
> as p1 would be pointing to p2 now. Please let me know where my
> understanding is going wrong?
p1 *is* p2. There are to references (p1 and p2) to the string initially
assigned to p1. Both have to go out of scope for the string to be deleted.
--
Ian Collins
== 3 of 6 ==
Date: Sun, Feb 2 2014 6:09 pm
From: somenath
On Monday, February 3, 2014 6:53:44 AM UTC+5:30, Ian Collins wrote:
> somenath wrote:
>
> > I am not able to understand the behavior of the following program
>
> >
>
> > #include <iostream>
>
> > #include<memory>
>
> > #include<string>
>
> > using namespace std;
>
> >
>
> > int main() {
>
> > auto p1 = make_shared<string> (10,'S');
>
> > cout<<"p1 use_count = "<<p1.use_count()<<endl;
>
> > shared_ptr<string> p2(new string()) ;
>
> > p1 = p2;
>
> > cout<<"p2 use_count = "<<p2.use_count()<<endl;
>
> > cout<<"second p1 use_count = "<<p1.use_count()<<endl;
>
> > return 0;
>
> > }
>
> > Output
>
> > ++++++++++++++++
>
> > p1 use_count = 1
>
> > p2 use_count = 2
>
> > second p1 use_count = 2
>
> >
>
> > I can understand the first two print. At beginning p1 points to one
>
> > string so the reference count is 1. When the statement p1=p2;
>
> > executes p2's reference count gets incremented to 2 but at the same
>
> > time I was expecting that p1's reference count to be decremented by 1
>
> > as p1 would be pointing to p2 now. Please let me know where my
>
> > understanding is going wrong?
>
>
>
> p1 *is* p2. There are to references (p1 and p2) to the string initially
>
> assigned to p1. Both have to go out of scope for the string to be deleted.
>
I couldn't follow you. Why p2 would refer to the "string initially
assigned to p1"?
p2 is defined as follows
shared_ptr<string> p2(new string())
So according to my understanding p2 would refer to the empty string.
Then when the statement p1=p2; gets executed p1 also start referring to what ever p2 referring to. So the reference count of p2 will increase and also hoped that p1's reference count to be decremented by 1 but that does not happen.
I think this way because the book I refer for understanding these concept says.
"We can think of shared_ptr as if it has an associated counter,usually referred to as a reference count.
..
..
p=q p and q are shared_ptrs holding pointers that can be converted to one another. Decrements p's reference count and increments q's count; deletes p's existing memory if p's count goes to 0"
But I think it is better to think reference count as the count of pointers pointing to some memory location. In that case according to my program the following statement
p1=p2;
will increase the reference count of the memory location that p2 point as p1 also point to the same location.As p1 also point to the same meory location so when I print p1's reference count it prints the same count as p2.
cout<<"second p1 use_count = "<<p1.use_count()<<endl;
Please help me to get my understanding correct.
--
Somenath
== 4 of 6 ==
Date: Sun, Feb 2 2014 6:29 pm
From: Ian Collins
somenath wrote:
> On Monday, February 3, 2014 6:53:44 AM UTC+5:30, Ian Collins wrote:
>>
>>
>> p1 *is* p2. There are to references (p1 and p2) to the string
>> initially
>>
>> assigned to p1. Both have to go out of scope for the string to be
>> deleted.
> I couldn't follow you. Why p2 would refer to the "string initially
> assigned to p1"? p2 is defined as follows
*Please clean up the awful mess google makes of your quotes!*
> shared_ptr<string> p2(new string()) So according to my understanding
> p2 would refer to the empty string. Then when the statement p1=p2;
> gets executed p1 also start referring to what ever p2 referring to.
> So the reference count of p2 will increase and also hoped that p1's
> reference count to be decremented by 1 but that does not happen.
I got p1 and p2 back to front, but the main point is still the same:
they both refer to the same object, so they must have the same reference
count.
> I think this way because the book I refer for understanding these
> concept says. "We can think of shared_ptr as if it has an associated
> counter,usually referred to as a reference count. ... ... p=q p and
> q are shared_ptrs holding pointers that can be converted to one
> another. Decrements p's reference count and increments q's count;
> deletes p's existing memory if p's count goes to 0"
This happens to p in the assignment operator, before the value pf q is
assigned to it.
> But I think it is better to think reference count as the count of
> pointers pointing to some memory location. In that case according to
> my program the following statement p1=p2; will increase the
> reference count of the memory location that p2 point as p1 also point
> to the same location.As p1 also point to the same meory location so
> when I print p1's reference count it prints the same count as p2.
> cout<<"second p1 use_count = "<<p1.use_count()<<endl; Please help
> me to get my understanding correct.
It does appear to be correct.
--
Ian Collins
== 5 of 6 ==
Date: Sun, Feb 2 2014 6:57 pm
From: Richard Damon
On 2/2/14, 9:09 PM, somenath wrote:
> I couldn't follow you. Why p2 would refer to the "string initially
> assigned to p1"?
> p2 is defined as follows
>
> shared_ptr<string> p2(new string())
> So according to my understanding p2 would refer to the empty string.
> Then when the statement p1=p2; gets executed p1 also start referring to what ever p2 referring to. So the reference count of p2 will increase and also hoped that p1's reference count to be decremented by 1 but that does not happen.
>
> I think this way because the book I refer for understanding these concept says.
> "We can think of shared_ptr as if it has an associated counter,usually referred to as a reference count.
> ..
> ..
> p=q p and q are shared_ptrs holding pointers that can be converted to one another. Decrements p's reference count and increments q's count; deletes p's existing memory if p's count goes to 0"
>
> But I think it is better to think reference count as the count of pointers pointing to some memory location. In that case according to my program the following statement
> p1=p2;
> will increase the reference count of the memory location that p2 point as p1 also point to the same location.As p1 also point to the same meory location so when I print p1's reference count it prints the same count as p2.
> cout<<"second p1 use_count = "<<p1.use_count()<<endl;
> Please help me to get my understanding correct.
> --
> Somenath
>
At the assigment of
p1 = p2;
First p1 is made to point to what p2 points to and that reference count
is increased.
The reference count for what p1 *used* to point to, is decremented (as
it no longer points to it), and if it goes to 0, that object is deleted.
== 6 of 6 ==
Date: Mon, Feb 3 2014 10:33 am
From: Marcel Müller
On 03.02.14 03.09, somenath wrote:
> I couldn't follow you. Why p2 would refer to the "string initially
> assigned to p1"?
> p2 is defined as follows
>
> shared_ptr<string> p2(new string())
> So according to my understanding p2 would refer to the empty string.
> Then when the statement p1=p2; gets executed p1 also start referring to what ever p2 referring to. So the reference count of p2 will increase and also hoped that p1's reference count to be decremented by 1 but that does not happen.
The reference counter is no property of the shared_ptr. It is a property
of the objects where the shared_ptr points to.
> I think this way because the book I refer for understanding these concept says.
> "We can think of shared_ptr as if it has an associated counter,usually referred to as a reference count.
shared_ptr instances do not have a reference counter.
> p=q p and q are shared_ptrs holding pointers that can be converted to one another. Decrements p's reference count and increments q's count; deletes p's existing memory if p's count goes to 0"
The reference counter of *p and *q are modified. p and q do not have
reference counters.
> But I think it is better to think reference count as the count of pointers pointing to some memory location. In that case according to my program the following statement
> p1=p2;
> will increase the reference count of the memory location that p2 point as p1 also point to the same location.As p1 also point to the same meory location so when I print p1's reference count it prints the same count as p2.
This is exactly what's going on.
> cout<<"second p1 use_count ="<<p1.use_count()<<endl;
> Please help me to get my understanding correct.
Internally shared_ptr uses helper objects to add the reference counter
to arbitrary objects. So your code effectively does the following:
auto p1 = make_shared<string> (10,'S');
tmp1 = new string#1(10,'S')
tmp2 = new helper_obj#1(1, tmp1)
p1 = shared_ptr(tmp2)
result:
p1 -> helper_obj#1{ counter = 1, content -> string#1{"SSSSSSSSSS"} }
cout<<"p1 use_count = "<<p1.use_count()<<endl;
shared_ptr<string> p2(new string()) ;
tmp1 = new string#2()
tmp2 = new helper_obj#2(1, tmp2)
p2 = shared_ptr(tmp2)
result:
p1 -> helper_obj#1{ counter = 1, content -> string#1{"SSSSSSSSSS"} }
p2 -> helper_obj#2{ counter = 1, content -> string#2{} }
p1 = p2;
++p2->counter
--p1->counter
because p1->counter goes to zero:
delete helper_obj#1
delete string#1
result:
p2 -> helper_obj#2{ counter = 2, content -> string#2{} }
p1 -> helper_obj#2{ counter = 2, content -> string#2{} }
cout<<"p2 use_count = "<<p2.use_count()<<endl;
cout<<"second p1 use_count = "<<p1.use_count()<<endl;
The helper objects cause additional allocations and more importantly an
additional indirection at every access to the stored strings. But they
are required to store arbitrary objects in shared_ptr instances.
Marcel
==============================================================================
TOPIC: Boost
http://groups.google.com/group/comp.lang.c++/t/81738d66827a11c8?hl=en
==============================================================================
== 1 of 3 ==
Date: Sun, Feb 2 2014 8:42 pm
From: woodbrian77@gmail.com
On Sunday, February 2, 2014 6:46:25 AM UTC-6, Öö Tiib wrote:
> On Sunday, 2 February 2014 01:46:29 UTC+2, woodb...@gmail.com wrote:
>
> > A company could ask us to store a particular version.
> > If we know about it, I don't see a problem with that.
> > There would be some administrative work around it, but
> > it doesn't seem like too big a deal. We'll automate
> > it if there's enough interest.
>
> They need to build tests and then patched version of
> the 10 year old product. How does their build system
> integrate with your online code generator? How does it
> integrate now? How will it integrate 10 years later?
It's the user's responsibility to tell us they want
us to save a snapshot of the service. Besides doing
that they would need to save whatever they use for
their build system. The company Ian described is
already doing that.
As far as today, I'm using make. If a dependency is
updated, a command is run that causes the generated code
to be refreshed.
I don't know how this will work ten years down
the road, but changes won't mean we can't help
someone who needs an old version of the software.
We'll save what we can, but we can't save something
that isn't part of the service. That's the user's
responsibility.
> Are you alive 10 years later?
>
We had discussion previously of Elijah and Elisha.
Elijah trained Elisha to take over for him and
Elisha did just that. Beyond that I'm in fairly
good shape. I walk and jog for exercise. I have
regular physicals, brush my teeth twice a day and
floss once a week. I'm mostly a vegetarian and
eat healthy foods. I've never used tobacco, never
tried any drugs and drink just a little beer. I
enjoy programming and the freedom I have to make
a variety of decisions around the company. My
goal is to create the best software company in
the world.
>
>
> Most opponents of usage of Boost speak some sort of NIH
> and FUD rhetoric, despite all source code is available
> (including 10+ years old versions) from several sources
> and heavily peer-reviewed. How you overcome that with
> your service?
My advice with Boost is to "chew the meat and spit
the bones." Some of Boost is really good.
I've had some peer review and welcome more of that!
We have a different model though than Boost. Boost
has only libraries I think. We have both executables
and a library. Our executables use the library so we
are first user of the code. Are you familiar with
the phrase eating your own dog food? We use code
generated by previous versions of the C++ Middleware
Writer to build new versions of it. Good projects
eat their own dog food in my opinion.
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
== 2 of 3 ==
Date: Sun, Feb 2 2014 10:04 pm
From: woodbrian77@gmail.com
On Sunday, February 2, 2014 7:21:44 AM UTC-6, Dombo wrote:
> Op 01-Feb-14 22:11, woodbrian77@gmail.com schreef:
>
>
> It is still not clear to me what is the benefit for the client is of
> online code generation.
>
One benefit over some of the competition is automating
the creation of marshalling functions. C# and Java
have been ahead of C++ is this area, but the C++
Middleware Writer goes beyond what those languages
have by being on line.
>
> > I'm not sure where you've looked.
>
> I've seen your posts here, and I've looked at your website, and found
> nothing to support your assertion that you are outsmarting your 'bigger
> competitors'. In fact I get the impression you don't even are aware of
> many of the well known alternatives for your offering out there.
>
> The impression I get is that CMW is little more than a personal hobby
> project with very little or no use from anyone else.
>
It is a small company. Recall this though from
Yeshua (aka Jesus):
He presented another parable to them, saying, "The
kingdom of heaven is like a mustard seed, which a
man took and sowed in his field; and this is smaller
than all other seeds, but when it is full grown, it
is larger than the garden plants and becomes a tree,
so that the birds of the air come and nest in its
branches." Matthew 13:31, 32
We have taken what was once considered to be an
unusual approach, but is now understood to be the
correct approach? I mean going on line. Is
Microsoft going to abandon Office 365? Don't be
silly.
> > Some "successful" companies like Southwest Airlines
> > and Facebook have had to learn the hard way that
> > the languages they were using didn't scale well.
> > I've been using C++ from the beginning. Work done
> > on the foundation may not be easy to notice, but it
> > provides for the long term future of the company.
>
> Whether C++ is the appropriate choice for Facebook or Southwest Airlines
> is not the subject being discussed here. Nor does it explain why a
> online tool would be better from a longevity perspective.
>
> >
> > I acknowledge the website could be better and the
> > documentation also. I've been asking for ideas on
> > how to improve that. If you have some specific
> > ideas on that, please let me know.
>
> Ask yourself what incentive people have to spend time and energy to
> provide consultancy to improve your offering.
>
The person who gives an answer usually learns something
by posting and they get some recognition from others
for contributing something helpful.
I don't know what everyone's motives are.
But the Bible encourages us to ask, seek and knock.
I've done that and have gotten a lot of helpful advice
along the way. Roughly seven years ago we had a web-
based interface to the code generator. That seemed
like the way to go 10+ years ago. Then someone on
a Boost list suggested that it should be something
that could be integrated into build environments. It
didn't take me too long to figure out that was right.
I have a track record of contemplating advice and
taking what makes sense to me and bringing it to
fruition. Slow and steady wins the race.
> > Beggars can't be choosers as far as who they are going
> > to rely on.
>
> You are assuming that your potential customers are beggars. And even if
> that is true (I hope for your sake it isn't) there are plenty of free-
> and paid alternatives to choose from.
>
The Statue of Liberty has this: "Give us your tired,
your poor, your huddled masses yearning to breathe free."
There are many friendly, intelligent poor people out
there. They don't have much money, but that's fine.
They have the time and the desire to buid things. We're
here to help them.
I'm mostly familiar with free alternatives. Paid
alternatives have a hard time gaining traction with
the poor.
If a company wants to use a binary copy of the C++
Middleware Writer, I'm happy to talk to them about that.
It isn't free though in that case.
>
> > If you are drowning and someone offers
> > to help you, are you going to turn them down if they
> > don't have a lifeguard certification?
>
> In your analogy I would be already surrounded by certified lifeguards.
> So why would I send the certified lifeguards away in favor of someone
> who is struggling to stay afloat himself?
The company is in better shape than ever. The company has
no debts. Some well known companies have more debt than
assets. We have some money for new hardware this year.
>
> There are already many well known and proven alternatives for what you
> are offering. The question remains in what way your solution improves on
> what there is already out there.
>
Ebenezer Enterprises has been built from the beginning
with an understanding of the cyclical (Purim, Pesach, ...
Sukkot, Hanukkah ...) nature of reality. I don't think the
competition can say the same thing.
See also my previous reply about how we eat our own dog food.
Boost wasn't built that way.
> > I'm willing to help a company get their mojo back.
>
> I don't mean to be harsh, but frankly I doubt you have what it takes to
> do that.
I look forward to showing otherwise.
Brian
Ebenezer Enterprises - "It's not the size of the dog
in the fight, but the size of the fight in the dog."
http://webEbenezer.net
== 3 of 3 ==
Date: Mon, Feb 3 2014 2:37 am
From: Öö Tiib
On Monday, 3 February 2014 06:42:15 UTC+2, woodb...@gmail.com wrote:
> On Sunday, February 2, 2014 6:46:25 AM UTC-6, Öö Tiib wrote:
> > Most opponents of usage of Boost speak some sort of NIH
> > and FUD rhetoric, despite all source code is available
> > (including 10+ years old versions) from several sources
> > and heavily peer-reviewed. How you overcome that with
> > your service?
>
> My advice with Boost is to "chew the meat and spit
> the bones." Some of Boost is really good.
>
> I've had some peer review and welcome more of that!
You did not perhaps understand what I asked.
* Boost is better peer reviewed than most code.
Problem: lot of developers use NIH policy as excuse to
use their own, far crappier code.
* Boost is all open and available with "do what you want"
license. Documentation is not best but is far over average.
Problem: FUD; something feels still non-transparent.
So where is edge of yours here?
> We have a different model though than Boost. Boost
> has only libraries I think. We have both executables
> and a library.
Boost has rather small amount of executables (Build,
Wave and few others) indeed and code generation is
done mostly by meta-programming (that I don't like).
The functionality and flexibility of executables delivered
with Boost is likely larger than yours.
I feel that you avoid answering what it is that your
*CMW* *does* *better* than competition for example
Protocol Buffers. Where is the edge from what you are
above?
Being almost as good is bad argument. Why you
drag us into discussing wealth of your company?
Google is in OK shape. With such competitors it is
nonsense to discuss IMHO.
==============================================================================
TOPIC: template friend with local classes ?
http://groups.google.com/group/comp.lang.c++/t/1013c4946db48f70?hl=en
==============================================================================
== 1 of 1 ==
Date: Mon, Feb 3 2014 8:17 am
From: Helmut Jarausch
Hi
I'd like to replace the following definition with a typedef version
typedef double Scalar;
class Term {
class Add;
public:
Term() {}
virtual Scalar operator()(Scalar Arg) const { return Arg; }
friend Add& operator+(const Term& A, const Term& B);
};
by a template class
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// something like the following declaration is necessary,
// but how to pre-declare the local class Add of class Term
template <typename Scalar>
typename Term<Scalar>::Add& operator+(const Term<Scalar>& A, const Term<Scalar>& B);
template <typename Scalar>
class Term {
class Add;
public:
Term() {}
virtual Scalar operator()(Scalar Arg) const { return Arg; }
friend Add<Scalar>& operator+(const Term<Scalar>& A, const Term<Scalar>& B);
};
Is there a solution for my problem?
Many thanks for any hints,
Helmut
==============================================================================
TOPIC: Functor with recursive call
http://groups.google.com/group/comp.lang.c++/t/7c8534b6a9ab8b48?hl=en
==============================================================================
== 1 of 1 ==
Date: Mon, Feb 3 2014 9:12 am
From: "A"
thank you guys for your most excelent answers!
==============================================================================
You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.
To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en
To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com
To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en
To report abuse, send email explaining the problem to abuse@googlegroups.com
==============================================================================
Google Groups: http://groups.google.com/?hl=en
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment