Implementation of functions in math.h on clc-wiki

P

P.J. Plauger

nice hack!

I prefer to think of it as a logical completion of the original
specification, but thanks.
.....

It is, indeed! I hav not had a look at the implementation of _Dint in the
current case. But it looks quite obvious.

It's not as obvious as you might think. In fairness to Pietsch,
it looks like he did try to re-engineer the guts of the function
(so far he has only the float version). Still, copying the file
names, many internal implementation names, and the arbitrary
values for the return code is pushing things. In other cases,
you'll find dozens of lines of code copied almost verbatim,
including the coefficients of economized polynomials down to
the last digit. Some of those "small" modules represented days
or weeks of work, over a period of a couple of years -- they
are not the "one right way" to do things.
That's what I would sign for immediatelly.

I guess that if he had asked you for assistance, you would have helped to
solve some issues. Just copy and paste without asking is not the fine kind
...

Right. I have no problem with people reading my published code
and using it as inspiration for a new implementation. I've certainly
benefited over the years from reading tons of code; and I continually
garner ideas from competitors' code that I have access to. Copyright
covers the *expression* of an idea, not the idea itself. But that
expression can be hard won -- in programming it's often the difference
between working right in all the corner cases and not quite working
at oddball times. It deserves protection.
FULL ACK.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

Seemingly? It _is_ lightweight. The heavy lifting takes place in _Dint
itself.

And in structuring the whole library so that ceil can be a one-liner.
Check out some of the ceil functions in glibc before you dismiss
this one-liner so offhandedly.
It may be EVIDENCE of a serious infringement, but the real much more
serious infringement would be copying of the implementation of _Dint
itself.

Here's where we part company, and where I think you're being
uncharitable at best, naive at worst. Copyright covers a broad
spectrum of expressions. It is weakest at "functional writings"
where there is little latitude for variety. Thus, I don't blink
at a <math.h> header that includes:

double sin(double);

My eyebrows would go up at:

_CRTIMP double _CDECL sin(double);

because we define those macros to work one way under gcc and
another under Windows (to build DLLs). And if I saw:

inline double _CDECL sin(double _Left)
{ // return sine
return (_Sin(_Left, 0));
}

I'd consider it a full-bore ripoff, because there's a lot of
technology behind those few lines. This is not just EVIDENCE
of a serious infringement, IMO. The point is, with each stage
there's less function and more unique expression, hence less
excuse for somebody else expressing a thing the way I did,
and hence more evidence that they're piggybacking on what's
well protected by copyright.
Unless you have either a trademark on the name or a patent on
the idea of the function, someone could just as well implement their
own.

Right, and I've never said otherwise. In fact, I observed in an
earlier post that the alleged perp put more work than average
into reimplementing _Dint (_Fint to be precise), though I still
consider it arguably infringing because of all the unique
expression that's still copied.
Given the specification of "_Dint", this looks like a perfectly obvious
way of implementing ceil. If we lived in some bizarre parallel universe
where _Dint is in the standard C library and ceil is not, that's how _I_
would implement ceil.

Fine, but we don't. It became obvious only after lots of work and
rework on my part, some of it dating back over 40 years.
I'm not saying you're wrong, but equating the copying of a small and
possibly uncopyrightable mathematical formula that _uses_ _Dint, with
copying of the implementation of _Dint itself, seems dishonest.

You're lucky that I chose to take a walk to Starbucks before replying
to this post. You pervert what I actually said, then use it as an
excuse to accuse *me* of being dishonest. Nary a word against the
clear-cut case of infringement that's there for anyone with a copy
of my book to verify. You're stretching the bounds of both
"uncharitable" and "naive" at this point, and bordering on arrogant
and rude. (That wasn't what I intended to say before my daily latte.)

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

.....

Don't function calls like _Dint(), render the code non portable?

Nope, quite the contrary. By isolating floating-point format
peculiarities in a handful of primitives, you *ease* the task
of writing scads of portable code. Adapting the primitives to
the formats of interest then leverages quite a bit of technology.
I don't understand the point of the posted clc-wiki.net library.
What was one supposed to have been able to do with it?
Was it supposed to have been instructional or of practical use,
or even compilable?

I don't think this is very instructional:
"You just call _Dint (&x, 0),
and now you know how ceil can be implemented."
and I don't undestand
what I was supposed to have been able to do with that code.

What you're missing is that _Dint is also provided, along with
the family of floating-point primitives I've developed over
the years. Aside from the *idea* of using those primitives,
which is arguably not protected by copyright, the implementation
of some of them involves a lot of literal copying from my work.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
C

Christian Bau

"P.J. Plauger said:
It's not as obvious as you might think. In fairness to Pietsch,
it looks like he did try to re-engineer the guts of the function
(so far he has only the float version). Still, copying the file
names, many internal implementation names, and the arbitrary
values for the return code is pushing things. In other cases,
you'll find dozens of lines of code copied almost verbatim,
including the coefficients of economized polynomials down to
the last digit.

Just a small comment: The coefficients of the polynomials can often be
chosen over a wide range; the lower coefficients are relatively strictly
determined, but there is quite a bit of leeway for the higher
coefficients. So the coefficient for x^3 in the calculation of the sine
function is quite likely the same everywhere, but if the coefficient for
x^15 matches to the last digit, then someone copied it.
 
P

P.J. Plauger

Just a small comment: The coefficients of the polynomials can often be
chosen over a wide range; the lower coefficients are relatively strictly
determined, but there is quite a bit of leeway for the higher
coefficients. So the coefficient for x^3 in the calculation of the sine
function is quite likely the same everywhere, but if the coefficient for
x^15 matches to the last digit, then someone copied it.

Basically true, but some of the coefficients in the library are
economized, which alters even the lowest-order terms. The latest
Dinkumware libraries use minimax techniques as well, which spread
the "creativity" even more widely over the coefficients. Aside
from the thousands of hours of computer time we've consumed over
the past several years, which arguably doesn't cost much these
days, we've also devoted the odd thousand hours of people time,
which is the realest expense we have. (It's the Ltd. part of
Dinkumware, Ltd.)

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
J

John F

P.J. Plauger said:
I prefer to think of it as a logical completion of the original
specification, but thanks.

I did mean it the right way round :)
It's not as obvious as you might think. In fairness to Pietsch,
it looks like he did try to re-engineer the guts of the function
(so far he has only the float version). Still, copying the file
names, many internal implementation names, and the arbitrary
values for the return code is pushing things. In other cases,
you'll find dozens of lines of code copied almost verbatim,
including the coefficients of economized polynomials down to
the last digit. Some of those "small" modules represented days
or weeks of work, over a period of a couple of years -- they
are not the "one right way" to do things.

Numerical optimisation is a though subject where propagation of errors
is one of the biggest issues which is non trivial at least...
Which optimisazions did you use? I have done three methods so far with
intermediate success (no time to use MatLab for extended
simulation...). Chebychev is one of my favourites. I'm trying to catch
up with more numerics but I just don't have enough time to.
Right. I have no problem with people reading my published code
and using it as inspiration for a new implementation. I've certainly
benefited over the years from reading tons of code; and I
continually
garner ideas from competitors' code that I have access to. Copyright
covers the *expression* of an idea, not the idea itself. But that
expression can be hard won -- in programming it's often the
difference
between working right in all the corner cases and not quite working
at oddball times. It deserves protection.

I agree on that.

regards
John
 
R

Rod Pemberton

P.J. Plauger said:
For all its brevity, this is a remarkably telling example of the
distinct worth of a particular implementation. _Dint is indeed my
own invention, evolved over several decades of writing portable
and efficient math functions. It is *not* simply a C implementation
of an old Fortran function, despite the similarity of names. Note
that it takes a second argument. Instead:

_Dint(double *px, int n) clears all but the first n bits to the right
of the (true) binary point in the floating-point value *px, then
returns a code describing the nature of the *discarded* value.

_Dint(&x, -1) truncates x to the nearest *even* value, a critical
test in function pow that's messy to write otherwise.

_Dint(&x, 0) truncates x to an integer and returns zero only
if x was already an integer. It returns other codes if x was a
NaN, an infinity, or a denormal. A good way to kick off all
sorts of math functions.

_Dint(&x, 1) truncates x to the nearest multiple of 1/2, and
tells you whether the result was an exact multiple of 1/2.
Round to nearest, anyone?

_Dint(&x, 2) truncates x to the nearest multiple of 1/4, very
handy for determining a quadrant.

_Dint(&x, (FBITS - 1) / 2) helps split a value into pieces so
you can perform arbitrary-precision using normal floating-point
operations.

At a quick count, we use _Dint in four dozen places in the
Dinkumware C library. It's the binary analog to the most
important (IMO) innovation in the evolving IEEE-754R decimal
floating-point package -- the ability to round to a given
number of decimal digits. But you will notice that _Dint is
*not* specified by the C Standard, and it is *not* present in
other implementations of the Standard C library. (Nor is the
decimal analog in IEEE-754R so clearly delineated.)

I consider _Dint one of the more valuable components of the
Standard C library that I originally wrote and that is now
being licensed by my company, Dinkumware, Ltd. (my
principal source of income for the past decade or so). I
don't take lightly the notion that it can be copied and
used verbatim in ways that took me quite some time to
work out. That's why something as seemingly lightweight as:

return _Dint (&x, 0) < 0 && 0.0 < x ? x + 1.0 : x;

is IMO a serious infringement. It takes more than removing
two parens and adding a space to bring something new to the
party.

As the guys here know, I am not a strong supporter of copyrights. But,
despite what Jordan Abel says, _Dint is _NOT_ anywhere near an obvious
implementation. It is highly specialized as the four cases prove.
_Dint(double *px, int n) is especially non-obvious. Although I haven't seen
the other offending stuff, I have to strongly side with you (Plauger) that
this is proprietary.


Rod Pemberton
 
J

Jordan Abel

I prefer to think of it as a logical completion of the original
specification, but thanks.

Using it to implement pow() is clever, though.
It's not as obvious as you might think. In fairness to Pietsch, it
looks like he did try to re-engineer the guts of the function (so far
he has only the float version). Still, copying the file names, many
internal implementation names, and the arbitrary values for the return
code is pushing things. In other cases, you'll find dozens of lines of
code copied almost verbatim, including the coefficients of economized
polynomials down to the last digit.

Yeah. And those "magic numbers" probably aren't the best thing to post
on a wiki for newbies who want to know how a C library works, anyway.
For (say) a sine function, 0, 1, 0, -1, ... is a set of coefficients
that are probably more easily understood, if not necessarily leading to
as efficient or as precise an implementation.
Some of those "small" modules represented days or weeks of work, over
a period of a couple of years -- they are not the "one right way" to
do things.

OK, but the ceil() implementation is, as far as I can tell, pretty much
the only way to implement ceil in terms of _Dint, for whatever that's
worth. You could flip the conditional around and make it look different,
but it's fundamentally the same.
Right. I have no problem with people reading my published code
and using it as inspiration for a new implementation. I've certainly
benefited over the years from reading tons of code; and I continually
garner ideas from competitors' code that I have access to. Copyright
covers the *expression* of an idea, not the idea itself. But that
expression can be hard won -- in programming it's often the difference
between working right in all the corner cases and not quite working
at oddball times. It deserves protection.

Well, in any case - I know this whole episode has probably left a bad
taste in your mouth, so to speak, about the wiki and everything, but
what would your thoughts be on contributing to it? Maybe not to the c
library reimplementation, or even code at all, but it could always use
more people even just in general.
 
P

P.J. Plauger

I did mean it the right way round :)


Numerical optimisation is a though subject where propagation of errors is
one of the biggest issues which is non trivial at least...
Which optimisazions did you use? I have done three methods so far with
intermediate success (no time to use MatLab for extended simulation...).
Chebychev is one of my favourites. I'm trying to catch up with more
numerics but I just don't have enough time to.

For single-argument functions, we favor piecewise minimax fits
(ratio of polynomials) using Maplesoft. We patch around zeros
at irrational argument values with truncated Taylor series.
We use extended precision as needed, implemented as an array
of half-precision values of arbitrary length.

We've also developed special test generators that know about the
graininess of floating-point values, and the inherent sensitivity
in functions due both to high slopes and artifacts of
floating-point representation.

What could be simpler?

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

As the guys here know, I am not a strong supporter of copyrights. But,
despite what Jordan Abel says, _Dint is _NOT_ anywhere near an obvious
implementation. It is highly specialized as the four cases prove.
_Dint(double *px, int n) is especially non-obvious. Although I haven't
seen
the other offending stuff, I have to strongly side with you (Plauger) that
this is proprietary.

Thanks, but let's tease apart a few concepts:

I am a *strong supporter* of copyrights because they protect
the actual unique expression, which at the end of the day is
what we programmers produce by way of value added.

I am *strongly opposed* to patents because they grant monopolies
on ideas, which are too easy for all of us to reinvent and which,
in software, are too close to mathematical formulas, which the
US patent system did not intend to cover.

I am neutral about keeping software proprietary. I sympathize
with the FSF goal of making all source code accessible -- indeed
I've always made my source code available to through books and
reasonable licensing terms -- but if a company wants to keep
their stuff hidden that should be their prerogative.

The problem here is that, while I assert copyright over code
in the Standard C Library book, I did not keep it proprietary.
I don't mind the copying of ideas, but I strongly oppose the
copying of expression. I make my living licensing, enhancing,
and supporting that expression.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

Well, in any case - I know this whole episode has probably left a bad
taste in your mouth, so to speak, about the wiki and everything, but
what would your thoughts be on contributing to it? Maybe not to the c
library reimplementation, or even code at all, but it could always use
more people even just in general.

I'm not agin it, and I've been know to speak up when the urge
strikes, but I do this sort of thing 60 hours a week as my
profession, not as a hobby. I'm also getting old, and looking
forward to only doing it, say, 40 hours a week. Maybe when
things slow down a bit...

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
J

Jordan Abel

First, I would like to apologize. My tone did cross a line, and I'm
sincerely sorry.

And in structuring the whole library so that ceil can be a one-liner.
Check out some of the ceil functions in glibc before you dismiss
this one-liner so offhandedly.


Here's where we part company, and where I think you're being
uncharitable at best, naive at worst. Copyright covers a broad
spectrum of expressions. It is weakest at "functional writings"
where there is little latitude for variety. Thus, I don't blink
at a <math.h> header that includes:

My question is this:

Do you think that, if this is infringement, that /1/ is necessarily also
infringement? How about /2/? I think that if the first is, both my
examples are as well, and that's why i'm uncomfortable with the position
that the first is.

1/return _M_d2i(&x,0) >= 0 || x <= 0 ? x : x+1;


2/
if(__dI(&x,0)<0 && x > 0)
return x+1.;
else
return x;
double sin(double);

My eyebrows would go up at:

_CRTIMP double _CDECL sin(double);

because we define those macros to work one way under gcc and
another under Windows (to build DLLs).

I think mine would too, but i'd think of it as being strong evidence of
further 'lifting' rather than being copyright infringement in itself -
whatever you end up naming the macro, there's really only one way to
declare a cdecl function on gcc, and only one way to do so on msvc. /3/,
right? No idea what _CRTIMP does. dllexport? I'm certainly not
disagreeing that it should raise suspicion, just that it's copyright
infringement per se.

3/
#if defined(__GNUC__)
#define _CDECL __cdecl
#elif defined(WIN32)
#define _CDECL __attribute__((__cdecl__))
#endif

And if I saw:

inline double _CDECL sin(double _Left)
{ // return sine
return (_Sin(_Left, 0));
}

It's unlikely you're the first to think of bundling sine and cosine into
a single function. Again, the names very much should raise suspicion,
and I certainly didn't mean to fault you for that - but the core imple-
mentation itself would be the actual infringement. I think part of it is
that I strongly disagree that changing the names should have any effect
on whether it's copyright infringement or not, since identifiers aren't
really the expressive part of code. I'm sure you probably agree that if
someone stole your code it would be made any better if they ran it
through an obfuscator to change all the identifiers.

I think that if inline double _CDECL sin(double _Left) { return (_Sin
(_Left, 0)); } is infringement, it is implicit that inline double
__cdecl__ sin(double _M_angle) { return (_M_sin(_M_angle,0)); } must
also be. That is what makes me uncomfortable about your position.
I'd consider it a full-bore ripoff, because there's a lot of
technology behind those few lines.

Yes, but in my opinion you'd have to look behind them, not in them, to
find the actual ripoff.
This is not just EVIDENCE of a serious infringement, IMO. The point
is, with each stage there's less function and more unique expression,
hence less excuse for somebody else expressing a thing the way I did,
and hence more evidence that they're piggybacking on what's well
protected by copyright.


Right, and I've never said otherwise. In fact, I observed in an
earlier post that the alleged perp put more work than average
into reimplementing _Dint (_Fint to be precise), though I still
consider it arguably infringing because of all the unique
expression that's still copied.


Fine, but we don't. It became obvious only after lots of work and
rework on my part, some of it dating back over 40 years.

ceil itself did? The idea of having a _Dint() function [and the details
of its specification, etc] did? or are we talking about the implement-
ation of _Dint()? No offense intended, I'm just confused here.
You're lucky that I chose to take a walk to Starbucks before replying
to this post. You pervert what I actually said, then use it as an
excuse to accuse *me* of being dishonest. Nary a word against the
clear-cut case of infringement that's there for anyone with a copy
of my book to verify.

Sorry - I don't have a copy of your book so I didn't feel qualified to
comment on that in either direction. I still don't believe that there's
that much variation possible in ceil() itself, and i hadn't even looked
at either the _Dint implementation on there, or, obviously, yours [since
i don't have the book]

To clarify my position: I think that the whole of what was there was
clearly infringement, just that ceil(), had it been present in isolation
with nothing else but an entirely reimplemented _Dint() wouldn't have
been. (though, the broader idea of using a function like _Dint() in the
implementation of other functions still might have been. I don't yet
have an opinion on that)
You're stretching the bounds of both "uncharitable" and "naive" at
this point, and bordering on arrogant and rude. (That wasn't what I
intended to say before my daily latte.)

Again, i'm sorry.
 
J

John F

P.J. Plauger said:
For single-argument functions, we favor piecewise minimax fits
(ratio of polynomials) using Maplesoft.

Maple is a good tool, I'll try to get back to those interesting stuff.
We patch around zeros
at irrational argument values with truncated Taylor series.
We use extended precision as needed, implemented as an array
of half-precision values of arbitrary length.

This could lead to almost infinite precision when used iteratively.
Would be interesting to see a high precision scientific library ...
maybe it will need some speed optimisazion then ... *thoughts running
through my head*
We've also developed special test generators that know about the
graininess of floating-point values, and the inherent sensitivity
in functions due both to high slopes and artifacts of
floating-point representation.

That could come in handy now and then when it comes to tweaking
control algorithms for µm precision lab instrumentory...
What could be simpler?

Good question ;-) If you know how to do it, nothing is complicated ...
Devil is in details and I'm as sure as I am real that you had a few
puzzles to solve on the algorithms (especially to make them
efficient...)

regards
John
 
R

Rod Pemberton

P.J. Plauger said:
I don't mind the copying of ideas, but I strongly oppose the
copying of expression. I make my living licensing, enhancing,
and supporting that expression.

So, one can use the exact same idea that you presented, as long as that
exact same idea is expressed in a completely different manner?

If everyone was held to that, it would essentially make all of mathematics,
physics, and most of computer programming, unuseable. I guess what I'm
trying to get at is: at what point does a certain author's presentation of
say, the Pythagorean Theorem, become copyrightable? How many ways can one
express this idea: "the rose is red," before it becomes uniquely
distinquishable enough to be copyrighted? Your use of _Dint was unique IMO.
But, how exactly could one use that same idea without expressing it in the
same unique manner? You seem to contradict yourself. You said you opposed
software patents, but yet it is very unlikely someone will be able to come
up with a different manner to express the ideas of _Dint without using your
exact form of expression. Essentially, you have a software patent through
copyright.


Rod Pemberton
 
P

P.J. Plauger

First, I would like to apologize. My tone did cross a line, and I'm
sincerely sorry.

Apology accepted. Thanks.
.....
My question is this:

Do you think that, if this is infringement, that /1/ is necessarily also
infringement? How about /2/? I think that if the first is, both my
examples are as well, and that's why i'm uncomfortable with the position
that the first is.

1/return _M_d2i(&x,0) >= 0 || x <= 0 ? x : x+1;


2/
if(__dI(&x,0)<0 && x > 0)
return x+1.;
else
return x;

You can fuzz the line until the cows come home. My initial
observation was that the one-liner ceil was pretty clearly
infringing in its own right because:

a) it differed only in whitespace and redundant parens from the
expression I used, down to the funny name for the internal function
_Dint, and

b) it was built around an inventive approach to ceil that I've
never seen in another implementation (down to the nuts and bolts,
even though said nuts and bolts did not appear in the one-liner)

Changing names is a step away, as is restating the algorithm.
How far is far enough? Operationally, it's probably when you've
made enough changes that you have a new debugging task on your
hands, and you're not just piggybacking on the testing and
debugging done for the prototype that inspired you. I don't
pretend it's a bright line in general. But I think it was in
the originally presented particular case for ceil.
I think mine would too, but i'd think of it as being strong evidence of
further 'lifting' rather than being copyright infringement in itself -

Uh, to me that's a distinction without a difference. You still
seem to think that infringement only occurs after a certain
number of yards of code have been replicated. In literature,
you can infringe:

a book copyright by copying half a page without attribution or
permission

a screenplay by imitating the principal characters and plot outline

a poem by quoting one plangent line

It depends more on the creative freight than the length of the
train.
whatever you end up naming the macro, there's really only one way to
declare a cdecl function on gcc, and only one way to do so on msvc. /3/,
right?

No, there are several. Part of my point.
No idea what _CRTIMP does. dllexport? I'm certainly not
disagreeing that it should raise suspicion, just that it's copyright
infringement per se.

3/
#if defined(__GNUC__)
#define _CDECL __cdecl
#elif defined(WIN32)
#define _CDECL __attribute__((__cdecl__))
#endif

Good guess, but off the mark. The creativity can also come in
*where* you put the _CDECL decorations, as well as what they
expand to.
It's unlikely you're the first to think of bundling sine and cosine into
a single function.

Right, but making the second argument a quadrant offset is not
widely done. Nor is the naming convention. Nor, necessarily, is
the direct call to the common internal function from a C++ inline
and a C macro. etc. etc.
Again, the names very much should raise suspicion,
and I certainly didn't mean to fault you for that - but the core imple-
mentation itself would be the actual infringement. I think part of it is
that I strongly disagree that changing the names should have any effect
on whether it's copyright infringement or not, since identifiers aren't
really the expressive part of code. I'm sure you probably agree that if
someone stole your code it would be made any better if they ran it
through an obfuscator to change all the identifiers.

Sorry, but it's both. We all know that a good set of naming
conventions can materially aid the readability of code, and
hence contribute to its worth. At the same time, it's not
the whole value added, so mechanically altering the names
and retaining the code structure doesn't cut it either.
You can't say one aspect is the arena for determining
infringment and the other is not.
I think that if inline double _CDECL sin(double _Left) { return (_Sin
(_Left, 0)); } is infringement, it is implicit that inline double
__cdecl__ sin(double _M_angle) { return (_M_sin(_M_angle,0)); } must
also be. That is what makes me uncomfortable about your position.

Well, it doesn't have to. See above.
Yes, but in my opinion you'd have to look behind them, not in them, to
find the actual ripoff.

Another distinction without a difference. *Both* the foreground
and the background are part of the expression.
.....
Fine, but we don't. It became obvious only after lots of work and
rework on my part, some of it dating back over 40 years.

ceil itself did? The idea of having a _Dint() function [and the details
of its specification, etc] did? or are we talking about the implement-
ation of _Dint()? No offense intended, I'm just confused here.

IIRC, _Dint first arose as a safe way to perform the common operation
of ceil and floor, safely for large and semi-numeric values. It then
became apparent that several internal functions were so similar that
they should be merged, if only to lower the cost of porting. So
ceil and _Dint evolved back and forth, not in any simply directed
fashion (as top-down advocates would have you believe).
You're lucky that I chose to take a walk to Starbucks before replying
to this post. You pervert what I actually said, then use it as an
excuse to accuse *me* of being dishonest. Nary a word against the
clear-cut case of infringement that's there for anyone with a copy
of my book to verify.

Sorry - I don't have a copy of your book so I didn't feel qualified to
comment on that in either direction. I still don't believe that there's
that much variation possible in ceil() itself, and i hadn't even looked
at either the _Dint implementation on there, or, obviously, yours [since
i don't have the book]

I just grabbed three implementations of ceil from glibc. (There are
about two dozen.) They're attached below. Which one do you think looks
most like my implementation?

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


----
double
__ceil (double x)
{
if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */
{
double tmp1, new_x;

new_x = -x;
__asm (
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
#else
"cvttq/svm %2,%1\n\t"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(new_x), "=&f"(tmp1)
: "f"(new_x));

/* Fix up the negation we did above, as well as handling -0 properly.
*/
x = copysign(new_x, x);
}
return x;
}

----
#include <machine/asm.h>

RCSID("$NetBSD: s_ceil.S,v 1.4 1995/05/08 23:52:13 jtc Exp $")

ENTRY(__ceil)
fldl 4(%esp)
subl $8,%esp

fstcw 4(%esp) /* store fpu control word */

/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x0800,%edx /* round towards +oo */
orl 4(%esp),%edx
andl $0xfbff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */

frndint /* round */

fldcw 4(%esp) /* restore original control word */

addl $8,%esp
ret

----
#include "math.h"
#include "math_private.h"

#ifdef __STDC__
static const double huge = 1.0e300;
#else
static double huge = 1.0e300;
#endif

#ifdef __STDC__
double __ceil(double x)
#else
double __ceil(x)
double x;
#endif
{
int32_t i0,i1,j0;
u_int32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0<0) {i0=0x80000000;i1=0;}
else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) {
if(j0==20) i0+=1;
else {
j = i1 + (1<<(52-j0));
if(j<i1) i0+=1; /* got a carry */
i1 = j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
 
J

Jordan Abel

[sci.math removed]

I think mine would too, but i'd think of it as being strong evidence of
further 'lifting' rather than being copyright infringement in itself -
[>...]
It depends more on the creative freight than the length of the
train.

I think we're still in disagreement about how much "creative freight"
a wrapper function or a declaration [regardless of how much conditional
macro baggage may be present] has. But we'll have to agree to disagree I
guess. Again, sorry for my tone before.
No, there are several. Part of my point.

But you have to choose one, and the choice of which one is pretty much
arbitrary, isn't it?
The creativity can also come in *where* you put the _CDECL
decorations, as well as what they expand to.

Normally, I'd agree, but... again, it has to go somewhere. [well,
realistically, cdecl is the default, so you _could_ leave it off if
you can guarantee that it won't be compiled with options that will
change the default calling convention] there are a limited number of
choices, and when it comes down to it, the choice is pretty much
arbitrary. personally, i'd have put it after the prototype, unless
there was a compelling reason otherwise (say, some windows compiler
doesn't allow it there. but then there's no longer a choice.)
Right, but making the second argument a quadrant offset is not
widely done.

I didn't even realize that - does that mean that one can pass 2 to it to
get -sin(x) as well?
Nor is the naming convention.

_Word is one of a limited number of sane reserved identifier formats...
it's the one used by the new keywords in c99. I have no idea what the
significance of "left" is.
Nor, necessarily, is the direct call to the common internal function
from a C++ inline and a C macro. etc. etc.

That I'll buy. But inlines in headers as a general technique are common
enough.
Sorry, but it's both. We all know that a good set of naming
conventions can materially aid the readability of code, and hence
contribute to its worth. At the same time, it's not the whole value
added, so mechanically altering the names and retaining the code
structure doesn't cut it either. You can't say one aspect is the
arena for determining infringment and the other is not.


Well, it doesn't have to. See above.

I think we'll have to agree to disagree, and if that means that I end
up letting more things slide if I [unlikely] get famous and write a C
book, that's my loss.
IIRC, _Dint first arose as a safe way to perform the common operation
of ceil and floor, safely for large and semi-numeric values. It then
became apparent that several internal functions were so similar that
they should be merged, if only to lower the cost of porting. So
ceil and _Dint evolved back and forth, not in any simply directed
fashion (as top-down advocates would have you believe).
OK.
Sorry - I don't have a copy of your book so I didn't feel qualified to
comment on that in either direction. I still don't believe that there's
that much variation possible in ceil() itself, and i hadn't even looked
at either the _Dint implementation on there, or, obviously, yours [since
i don't have the book]

I just grabbed three implementations of ceil from glibc. (There are
about two dozen.) They're attached below. Which one do you think looks
most like my implementation?

<snipped>

fair enough.
 
P

P.J. Plauger

So, one can use the exact same idea that you presented, as long as that
exact same idea is expressed in a completely different manner?

Yes. That is sufficient, if not always necessary. I think you're
accusing me of saying it's always absolutely necessary. There
are degrees of acceptable difference, depending on the uniqueness
of each part of the expression.
If everyone was held to that, it would essentially make all of
mathematics,
physics, and most of computer programming, unuseable.

Nonsense. Perhaps you didn't notice what I said about functional
writings. If you ask three people to draw a floor plan for a warehouse,
you're going to get three pretty similar drawings (assuming they're
all basically competent). About the only way to infringe a blueprint
is to stuff it through a copier. Most of math and physics, and
great swaths of computer programming, aren't much different from
blueprints. But those parts of computer programming that are
deserve greater protection.
I guess what I'm
trying to get at is: at what point does a certain author's presentation of
say, the Pythagorean Theorem, become copyrightable?

A common touchstone is to ask, "Do you have to say it exacty
that way?" If there's only one sensible way to say something,
like x^2 + y^2 = z^2, then there's very little protection in
copyright law. But if you take the road less traveled, as it
were, you'd better not quote much more than the cliched part
of Robert Frost's great poem without getting permission.
How many ways can one
express this idea: "the rose is red," before it becomes uniquely
distinquishable enough to be copyrighted?

Good question. That's what poetry magazines traffic in, for
example.
Your use of _Dint was unique IMO.
But, how exactly could one use that same idea without expressing it in the
same unique manner?

Do you have to call it _Dint? There's no standard that says such
a critter exists. Does the first argument have to be a pointer
to double, and the second argument a signed integer bit offset?
Nothing like that in Fortran, IIRC. Do the return values have to
be defined in <math.h> as:

#define FP_INFINITE 2
#define FP_NAN 1
#define FP_NORMAL (-1)
#define FP_SUBNORMAL (-2)
#define FP_ZERO 0

(which was on the internet until a few hours ago, placed there
by a guy who asserted, "I'm writing a portable implementation of
the C standard library")? You might compare to this excerpt from
my <ymath.h>:

#define _DENORM (-2) /* C9X only */
#define _FINITE (-1)
#define _INFCODE 1
#define _NANCODE 2

(A little creativity there, but not much.) And so on, and so on.
None of these things *have* to be that way to implement the
clever idea of a fraction stripping function. So if you see a
ceil function that depends critically on a function spelled
the same way as yours, with the same signature as yours, with
almost identically the same return codes as yours -- with, in
fact, practically the same token sequence as yours -- is this
merely *evidence* of the possibility of infringement or is this
frigging infringement? I'd trust my fate to a dozen jurors
with no programming knowledge, just common sense, on that one.
You seem to contradict yourself.

No, it's more that you seem to want me to. I've been
reimplementing other people's software for decades, and
I've got a keen moral sense about when I think I've done
it fairly. Moreover, I've been double checked by the
likes of AT&T and tens of thousands of critical readers.
I work *hard* to make sure I have a consistent position
on infringement, one that I can apply equally to myself
and others.
You said you opposed
software patents, but yet it is very unlikely someone will be able to come
up with a different manner to express the ideas of _Dint without using
your
exact form of expression.

Hardly. See above.
Essentially, you have a software patent through
copyright.

Bullshit.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

.....

But you have to choose one, and the choice of which one is pretty much
arbitrary, isn't it?

Yep. All the more reason to be suspicious when someone makes
all the same arbitrary decisions you did. In arbitrariness
there is creative expression.
.....

I didn't even realize that - does that mean that one can pass 2 to it to
get -sin(x) as well?

Yep. In fact, a quick grep of our code shows that we use at least
four different forms for the second argument.
_Word is one of a limited number of sane reserved identifier formats...
it's the one used by the new keywords in c99. I have no idea what the
significance of "left" is.

True, but _Dint for a fraction stripping function, and _Left for the
left or only operand, etc.? The mere fact that the significance of
_Left doesn't leap out at you should make you wonder why some other
implementer should choose exactly the same funny name, neh?
That I'll buy. But inlines in headers as a general technique are common
enough.

So does that mean that you dismiss all declarations, macros, and
inlines as possible sources of infringement because all the other
teens at the sock hop are doin' it too?

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
J

Jordan Abel

A common touchstone is to ask, "Do you have to say it exacty that
way?" If there's only one sensible way to say something, like x^2 +
y^2 = z^2, then there's very little protection in copyright law. But
if you take the road less traveled, as it were, you'd better not quote
much more than the cliched part of Robert Frost's great poem without
getting permission.

If there is truly only one way to do something, we all agree (At least,
if i'm reading you correctly) that it's not copyrightable. What if there
are only two ways to do something? Are they both copyrightable? Is only
one? If there are more than two, are all but one copyrightable?

Does "well, you can say z^2-x^2=y^2", make x^2+y^2=z^2 copyrightable?
how about z=sqrt(x^2+y^2)?

[aside: given that the poem was written in 1920, it probably wasn't the
best example you might have used. But your point still stands, in
general]

[>...]
Nothing like that in Fortran, IIRC. Do the return values have to
be defined in <math.h> as:

#define FP_INFINITE 2
#define FP_NAN 1
#define FP_NORMAL (-1)
#define FP_SUBNORMAL (-2)
#define FP_ZERO 0

(which was on the internet until a few hours ago, placed there
by a guy who asserted, "I'm writing a portable implementation of
the C standard library")? You might compare to this excerpt from
my <ymath.h>:

#define _DENORM (-2) /* C9X only */
#define _FINITE (-1)
#define _INFCODE 1
#define _NANCODE 2

(A little creativity there, but not much.) And so on, and so on. None
of these things *have* to be that way to implement the clever idea of
a fraction stripping function. So if you see a ceil function that
depends critically on a function spelled the same way as yours, with
the same signature as yours, with almost identically the same return
codes as yours -- with, in fact, practically the same token sequence
as yours -- is this merely *evidence* of the possibility of
infringement or is this frigging infringement? I'd trust my fate to a
dozen jurors with no programming knowledge, just common sense, on that
one.

The question is whether the idea of "a function, whose first argument is
a pointer to double and whose second argument is int, returning int [0
if the double pointed at was zero, -1 if it is a normal number, -2 if it
is denormalized, 1 if it is infinite, 2 if it is not a number], and mod-
ifying the double pointed at, if normal or denormalized, such that it is
truncated to the number of bits right of the radix point specified in
the second argument" (this was intended to be an accurate and complete
description of your _Dint() function) is copyrightable. My description
of it may be, and your implementation is. But is the idea itself
copyrightable? Copyright law doesn't generally traffic in *ideas* - it's
like recipes - the set of steps themselves aren't copyrightable, only
the physical text of the recipe [the expression of those steps] is.
 
J

Jordan Abel

So does that mean that you dismiss all declarations, macros, and
inlines as possible sources of infringement because all the other
teens at the sock hop are doin' it too?

I just meant that if everything else were shown [however unlikely] to be
something someone came up with independently, that they're both inline
on top of that doesn't bring much to the party, so to speak.
 

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
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top