Bug 83845 - [libm] [patch] add log2() and log2f() support for libm
Summary: [libm] [patch] add log2() and log2f() support for libm
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: 7.0-CURRENT
Hardware: Any Any
: Normal Affects Only Me
Assignee: David Schultz
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-21 13:00 UTC by Roman Bogorodskiy
Modified: 2011-03-06 08:53 UTC (History)
0 users

See Also:


Attachments
msun_log2_and_log2f.diff (7.74 KB, patch)
2005-07-21 13:00 UTC, Roman Bogorodskiy
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Roman Bogorodskiy 2005-07-21 13:00:34 UTC
	Add e_log2.c and e_log2f.c files based on e_log.c and e_logf.c 
	respectively which adds support of C99 funtions log2() and log2f().

	The idea is simple:

	log(N) to base A is equal to logN/logA, that way, log2(x) = log(x)/log(2).
	So after some simplifications and deviding result by precalculated value of
	log(2) we can compute the value of the logarithm of argument x to base r2.

	Patch is attached. You can also pick it up here:
	http://people.freebsd.org/~novel/patches/freebsd/msun_log2_and_log2f.diff
Comment 1 David Schultz freebsd_committer freebsd_triage 2005-07-21 19:07:08 UTC
On Thu, Jul 21, 2005, Roman Bogorodskiy wrote:
> 	Add e_log2.c and e_log2f.c files based on e_log.c and e_logf.c 
> 	respectively which adds support of C99 funtions log2() and log2f().
> 
> 	The idea is simple:
> 
> 	log(N) to base A is equal to logN/logA, that way, log2(x) = log(x)/log(2).
> 	So after some simplifications and deviding result by precalculated value of
> 	log(2) we can compute the value of the logarithm of argument x to base r2.

Though this seems like a reasonable approach, it leads to
significant rounding errors since it requires dividing an inexact
result (ln(x) rounded to 52 bits) by another inexact quantity
(ln(2) rounded to 52 bits).  For instance, I suspect that if you
computed log2(2), log2(4), log2(8), log2(16), ... using your
implementation, the results would not always be exact.
Technically speaking I don't think they are required to be exact,
but common sense suggests that they ought to be.

A more minor objection is that log2() can be computed more quickly
than log(), but this impelementation does it less quickly.  This
isn't such a big deal, though; I'm more concerned about the
problem that accuracy guarantees will be significantly weaker than
for other routines in libm.

--David
Comment 2 Roman Bogorodskiy 2005-07-21 19:51:31 UTC
 David wrote:

> Though this seems like a reasonable approach, it leads to
> significant rounding errors since it requires dividing an inexact
> result (ln(x) rounded to 52 bits) by another inexact quantity
> (ln(2) rounded to 52 bits).  For instance, I suspect that if you
> computed log2(2), log2(4), log2(8), log2(16), ... using your
> implementation, the results would not always be exact.
> Technically speaking I don't think they are required to be exact,
> but common sense suggests that they ought to be.

Is not it exact?

$> ./a.out=20
log2(2) =3D 1.0000000000000000000000
log2(4) =3D 2.0000000000000000000000
log2(8) =3D 3.0000000000000000000000
log2(16) =3D 4.0000000000000000000000
$>=20

It's exact enough for me.

> A more minor objection is that log2() can be computed more quickly
> than log(), but this impelementation does it less quickly.  This
> isn't such a big deal, though; I'm more concerned about the
> problem that accuracy guarantees will be significantly weaker than
> for other routines in libm.

Ok. You know, log2() confirms to C99 and some apps become to use it now. Su=
re,=20
it's not problem for me to add hacks like #define log2(x) log(x)/log(2) whi=
le=20
you're looking for the ideal solution.

Roman Bogorodskiy
Comment 3 kargls 2005-07-23 03:02:15 UTC
See standards/82654.

I have implementations for several C99 long double math functions,
and in the process I implemented log2 and logf.  I also wrote or
edited the man pages.  IMHO, for log2[fl], we want to use frexp[fl]
to break x into x = f * 2**n where f is in the range [0.5,1).  We
then have  log2(x) = n + log2(f).  We can now either evaluate log2(f)
as log(f)/log(2) or directly use a polynomial approximation.

-- 
steve
Comment 4 Roman Bogorodskiy 2005-07-23 05:50:13 UTC
 Steven wrote:

> See standards/82654.
> 
> I have implementations for several C99 long double math functions,
> and in the process I implemented log2 and logf.  I also wrote or


That's really great, since our libmath is a bit outdated and nobody
seems to care about that.

> edited the man pages.  IMHO, for log2[fl], we want to use frexp[fl]
> to break x into x = f * 2**n where f is in the range [0.5,1).  We
> then have  log2(x) = n + log2(f).  We can now either evaluate log2(f)
> as log(f)/log(2) or directly use a polynomial approximation.


That looks reasonable. Actually, I don't care which implementation will
be used, your or mine or some another, I'd just like to have it
implemented. But looking at the batch of open standarts PRs I think we
have no chance to get it committed in the near future. :(

Roman Bogorodskiy
Comment 5 Mark Diekhans 2009-12-31 04:24:31 UTC
How about integrating the C99 math functions into libm?  This PR has been pending
for four years.  NetBSD already has them:

   http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libm/src/

Makes it hard to port software and to advocate for FreeBSD being a
standards-compliant platform.

Thanks
Mark
Comment 6 David Schultz freebsd_committer freebsd_triage 2010-12-03 00:08:58 UTC
Responsible Changed
From-To: freebsd-standards->das

Over to me. There have been numerous requests for this functionality.
Comment 7 David Schultz freebsd_committer freebsd_triage 2010-12-05 23:32:43 UTC
State Changed
From-To: open->patched

log2() and log2f() are implemented in r216210 and r216211.
Comment 8 David Schultz freebsd_committer freebsd_triage 2011-03-06 08:53:32 UTC
State Changed
From-To: patched->closed

merged to 8-stable in r219325