math.nbtheory: Implement natural logarithm
This commit is contained in:
parent
74b085b88d
commit
e4cd57a615
@ -5,9 +5,10 @@ rule archive
|
|||||||
command = ar rcs $out $in
|
command = ar rcs $out $in
|
||||||
|
|
||||||
build abs.o: gas x64/linux/math/abs.S
|
build abs.o: gas x64/linux/math/abs.S
|
||||||
|
build log.o: gas x64/linux/math/log.S
|
||||||
build cmp.o: gas x64/linux/memory/cmp.S
|
build cmp.o: gas x64/linux/memory/cmp.S
|
||||||
build fill.o: gas x64/linux/memory/fill.S
|
build fill.o: gas x64/linux/memory/fill.S
|
||||||
build copy.o: gas x64/linux/memory/copy.S
|
build copy.o: gas x64/linux/memory/copy.S
|
||||||
build syscall.o: gas x64/linux/syscall.S
|
build syscall.o: gas x64/linux/syscall.S
|
||||||
|
|
||||||
build tanya.a: archive syscall.o copy.o fill.o cmp.o abs.o
|
build tanya.a: archive syscall.o copy.o fill.o cmp.o log.o abs.o
|
||||||
|
48
arch/x64/linux/math/log.S
Normal file
48
arch/x64/linux/math/log.S
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
.text
|
||||||
|
|
||||||
|
|
||||||
|
// logl.
|
||||||
|
.globl _D5tanya4math8nbtheory2lnFNaNbNiNfeZe
|
||||||
|
.type _D5tanya4math8nbtheory2lnFNaNbNiNfeZe, @function
|
||||||
|
|
||||||
|
_D5tanya4math8nbtheory2lnFNaNbNiNfeZe:
|
||||||
|
fldln2 // Put lb(e) onto the FPU stack
|
||||||
|
fldt 8(%rsp) // Put the argument onto the FPU stack
|
||||||
|
fyl2x // %st1 * lb(%st0)
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
// log.
|
||||||
|
.globl _D5tanya4math8nbtheory2lnFNaNbNiNfdZd
|
||||||
|
.type _D5tanya4math8nbtheory2lnFNaNbNiNfdZd, @function
|
||||||
|
|
||||||
|
_D5tanya4math8nbtheory2lnFNaNbNiNfdZd:
|
||||||
|
movsd %xmm0, -8(%rsp) // Put the argument onto the stack
|
||||||
|
|
||||||
|
fldln2 // Put lb(e) onto the FPU stack
|
||||||
|
fldl -8(%rsp) // Put a double onto the FPU stack
|
||||||
|
fyl2x // %st1 * lb(%st0)
|
||||||
|
|
||||||
|
// The result is on the FPU stack, but returned in %xmm0
|
||||||
|
fstpl -8(%rsp)
|
||||||
|
movsd -8(%rsp), %xmm0
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
// logf.
|
||||||
|
.globl _D5tanya4math8nbtheory2lnFNaNbNiNffZf
|
||||||
|
.type _D5tanya4math8nbtheory2lnFNaNbNiNffZf, @function
|
||||||
|
|
||||||
|
_D5tanya4math8nbtheory2lnFNaNbNiNffZf:
|
||||||
|
movss %xmm0, -4(%rsp) // Put the argument onto the stack
|
||||||
|
|
||||||
|
fldln2 // Put lb(e) onto the FPU stack
|
||||||
|
flds -4(%rsp) // Put a float onto the FPU stack
|
||||||
|
fyl2x // %st1 * lb(%st0)
|
||||||
|
|
||||||
|
// The result is on the FPU stack, but returned in %xmm0
|
||||||
|
fstps -4(%rsp)
|
||||||
|
movss -4(%rsp), %xmm0
|
||||||
|
|
||||||
|
ret
|
@ -35,6 +35,7 @@ import tanya.memory;
|
|||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
|
import tanya.range.primitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown on encoding errors.
|
* Thrown on encoding errors.
|
||||||
@ -352,9 +353,9 @@ struct String
|
|||||||
* Precondition: $(D_INLINECODE allocator is null).
|
* Precondition: $(D_INLINECODE allocator is null).
|
||||||
*/
|
*/
|
||||||
this(S)(const S str, shared Allocator allocator = defaultAllocator)
|
this(S)(const S str, shared Allocator allocator = defaultAllocator)
|
||||||
if (!std.range.isInfinite!S
|
if (!isInfinite!S
|
||||||
&& std.range.isInputRange!S
|
&& isInputRange!S
|
||||||
&& isSomeChar!(std.range.ElementEncodingType!S))
|
&& isSomeChar!(ElementType!S))
|
||||||
{
|
{
|
||||||
this(allocator);
|
this(allocator);
|
||||||
insertBack(str);
|
insertBack(str);
|
||||||
@ -667,12 +668,12 @@ struct String
|
|||||||
* Throws: $(D_PSYMBOL UTFException).
|
* Throws: $(D_PSYMBOL UTFException).
|
||||||
*/
|
*/
|
||||||
size_t insertBack(R)(R str) @trusted
|
size_t insertBack(R)(R str) @trusted
|
||||||
if (!std.range.isInfinite!R
|
if (!isInfinite!R
|
||||||
&& std.range.isInputRange!R
|
&& isInputRange!R
|
||||||
&& is(Unqual!(std.range.ElementEncodingType!R) == char))
|
&& is(Unqual!(ElementType!R) == char))
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
static if (std.range.hasLength!R || isNarrowString!R)
|
static if (hasLength!R || isNarrowString!R)
|
||||||
{
|
{
|
||||||
size = str.length + length;
|
size = str.length + length;
|
||||||
reserve(size);
|
reserve(size);
|
||||||
@ -731,11 +732,11 @@ struct String
|
|||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
size_t insertBack(R)(R str) @trusted
|
size_t insertBack(R)(R str) @trusted
|
||||||
if (!std.range.isInfinite!R
|
if (!isInfinite!R
|
||||||
&& std.range.isInputRange!R
|
&& isInputRange!R
|
||||||
&& is(Unqual!(std.range.ElementEncodingType!R) == wchar))
|
&& is(Unqual!(ElementType!R) == wchar))
|
||||||
{
|
{
|
||||||
static if (std.range.hasLength!R || isNarrowString!R)
|
static if (hasLength!R || isNarrowString!R)
|
||||||
{
|
{
|
||||||
reserve(length + str.length * wchar.sizeof);
|
reserve(length + str.length * wchar.sizeof);
|
||||||
}
|
}
|
||||||
@ -797,11 +798,11 @@ struct String
|
|||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
size_t insertBack(R)(R str) @trusted
|
size_t insertBack(R)(R str) @trusted
|
||||||
if (!std.range.isInfinite!R
|
if (!isInfinite!R
|
||||||
&& std.range.isInputRange!R
|
&& isInputRange!R
|
||||||
&& is(Unqual!(std.range.ElementEncodingType!R) == dchar))
|
&& is(Unqual!(ElementType!R) == dchar))
|
||||||
{
|
{
|
||||||
static if (std.range.hasLength!R || isSomeString!R)
|
static if (hasLength!R || isSomeString!R)
|
||||||
{
|
{
|
||||||
reserve(length + str.length * 4);
|
reserve(length + str.length * 4);
|
||||||
}
|
}
|
||||||
@ -1268,9 +1269,9 @@ struct String
|
|||||||
* Throws: $(D_PSYMBOL UTFException).
|
* Throws: $(D_PSYMBOL UTFException).
|
||||||
*/
|
*/
|
||||||
ref String opAssign(S)(S that) nothrow
|
ref String opAssign(S)(S that) nothrow
|
||||||
if (!std.range.isInfinite!S
|
if (!isInfinite!S
|
||||||
&& std.range.isInputRange!S
|
&& isInputRange!S
|
||||||
&& isSomeChar!(std.range.ElementEncodingType!S))
|
&& isSomeChar!(ElementType!S))
|
||||||
{
|
{
|
||||||
this.length_ = 0;
|
this.length_ = 0;
|
||||||
insertBack(that);
|
insertBack(that);
|
||||||
@ -1531,9 +1532,9 @@ struct String
|
|||||||
* Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
|
* Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
|
||||||
*/
|
*/
|
||||||
size_t insertAfter(T, R)(R r, T el) @trusted
|
size_t insertAfter(T, R)(R r, T el) @trusted
|
||||||
if ((isSomeChar!T || (!std.range.isInfinite!T
|
if ((isSomeChar!T || (!isInfinite!T
|
||||||
&& std.range.isInputRange!T
|
&& isInputRange!T
|
||||||
&& isSomeChar!(std.range.ElementEncodingType!T)))
|
&& isSomeChar!(ElementType!T)))
|
||||||
&& (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
|
&& (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -1564,9 +1565,9 @@ struct String
|
|||||||
|
|
||||||
///
|
///
|
||||||
size_t insertBefore(T, R)(R r, T el) @trusted
|
size_t insertBefore(T, R)(R r, T el) @trusted
|
||||||
if ((isSomeChar!T || (!std.range.isInfinite!T
|
if ((isSomeChar!T || (!isInfinite!T
|
||||||
&& std.range.isInputRange!T
|
&& isInputRange!T
|
||||||
&& isSomeChar!(std.range.ElementEncodingType!T)))
|
&& isSomeChar!(ElementType!T)))
|
||||||
&& (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
|
&& (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,15 @@ module tanya.math.nbtheory;
|
|||||||
import tanya.math.mp;
|
import tanya.math.mp;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
|
||||||
|
version (TanyaNative)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
import core.math : fabs;
|
||||||
|
import std.math : log;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the absolute value of a number.
|
* Calculates the absolute value of a number.
|
||||||
*
|
*
|
||||||
@ -57,21 +66,19 @@ version (D_Ddoc)
|
|||||||
I abs(I)(I x)
|
I abs(I)(I x)
|
||||||
if (isFloatingPoint!I);
|
if (isFloatingPoint!I);
|
||||||
}
|
}
|
||||||
else version (TanyaPhobos)
|
else version (TanyaNative)
|
||||||
|
{
|
||||||
|
extern I abs(I)(I number) pure nothrow @safe @nogc
|
||||||
|
if (isFloatingPoint!I);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
import core.math;
|
|
||||||
|
|
||||||
I abs(I)(I x)
|
I abs(I)(I x)
|
||||||
if (isFloatingPoint!I)
|
if (isFloatingPoint!I)
|
||||||
{
|
{
|
||||||
return fabs(cast(real) x);
|
return fabs(cast(real) x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
extern I abs(I)(I number) pure nothrow @safe @nogc
|
|
||||||
if (isFloatingPoint!I);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
pure nothrow @safe @nogc unittest
|
pure nothrow @safe @nogc unittest
|
||||||
@ -103,3 +110,56 @@ I abs(I : Integer)(I x)
|
|||||||
x.sign = Sign.positive;
|
x.sign = Sign.positive;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version (D_Ddoc)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Calculates natural logarithm of $(D_PARAM x).
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* x = Argument.
|
||||||
|
*
|
||||||
|
* Returns: Natural logarithm of $(D_PARAM x).
|
||||||
|
*/
|
||||||
|
float ln(float x) pure nothrow @safe @nogc;
|
||||||
|
/// ditto
|
||||||
|
double ln(double x) pure nothrow @safe @nogc;
|
||||||
|
/// ditto
|
||||||
|
real ln(real x) pure nothrow @safe @nogc;
|
||||||
|
}
|
||||||
|
else version (TanyaNative)
|
||||||
|
{
|
||||||
|
extern float ln(float x) pure nothrow @safe @nogc;
|
||||||
|
extern double ln(double x) pure nothrow @safe @nogc;
|
||||||
|
extern real ln(real x) pure nothrow @safe @nogc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float ln(float x) pure nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
return log(x);
|
||||||
|
}
|
||||||
|
double ln(double x) pure nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
return log(x);
|
||||||
|
}
|
||||||
|
alias ln = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pure nothrow @safe @nogc unittest
|
||||||
|
{
|
||||||
|
import tanya.math;
|
||||||
|
|
||||||
|
assert(isNaN(ln(-7.389f)));
|
||||||
|
assert(isNaN(ln(-7.389)));
|
||||||
|
assert(isNaN(ln(-7.389L)));
|
||||||
|
|
||||||
|
assert(isInfinity(ln(0.0f)));
|
||||||
|
assert(isInfinity(ln(0.0)));
|
||||||
|
assert(isInfinity(ln(0.0L)));
|
||||||
|
|
||||||
|
assert(ln(1.0f) == 0.0f);
|
||||||
|
assert(ln(1.0) == 0.0);
|
||||||
|
assert(ln(1.0L) == 0.0L);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user