// cl_ln2().

// General includes.
#include "cl_sysdep.h"

// Specification.
#include "cl_R_tran.h"


// Implementation.

#include "cl_lfloat.h"
#include "cl_LF.h"

cl_LF cl_ln2 (uintC len)
{
	var uintC oldlen = TheLfloat(cl_LF_ln2)->len; // vorhandene Länge
	if (len < oldlen)
		return shorten(cl_LF_ln2,len);
	if (len == oldlen)
		return cl_LF_ln2;

	// TheLfloat(cl_LF_ln2)->len um mindestens einen konstanten Faktor
	// > 1 wachsen lassen, damit es nicht zu häufig nachberechnet wird:
	var uintC newlen = len;
	oldlen += floor(oldlen,2); // oldlen * 3/2
	if (newlen < oldlen)
		newlen = oldlen;

	// gewünschte > vorhandene Länge -> muß nachberechnen:
	// Here, it is tricky to avoid a recursive loop. We assume that ln()
	// will not invoke cl_ln2() if its argument is between 2/3 and 4/3.
	// So we compute -2*ln(1/sqrt(2)).
	cl_LF_ln2 = -scale_float(ln(sqrt(scale_float(cl_I_to_LF(1,newlen),-1))),1);
	return (len < newlen ? shorten(cl_LF_ln2,len) : cl_LF_ln2);
}
