Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,2 +1,4 @@
---
category:
- Arithmetic
note: Arithmetic operations

View file

@ -0,0 +1,13 @@
#define generic_pow(base, exp)\
_Generic((base),\
double: dpow,\
int: ipow)\
(base, exp)
int main()
{
printf("2^6 = %d\n", generic_pow(2,6));
printf("2^-6 = %d\n", generic_pow(2,-6));
printf("2.71^6 = %lf\n", generic_pow(2.71,6));
printf("2.71^-6 = %lf\n", generic_pow(2.71,-6));
}

View file

@ -1,12 +1,12 @@
import std.stdio, std.conv;
struct Number(T) {
T x; // Base.
T x; // base
alias x this;
string toString() const { return text(x); }
Number opBinary(string op)(in int exponent)
const pure nothrow if (op == "^^") in {
const pure nothrow @nogc if (op == "^^") in {
if (exponent < 0)
assert (x != 0, "Division by zero");
} body {
@ -16,7 +16,7 @@ struct Number(T) {
T factor;
if (exponent < 0) {
zerodir = +1;
factor = (cast(T)1) / x;
factor = T(1) / x;
} else {
zerodir = -1;
factor = x;

View file

@ -0,0 +1,13 @@
sub ex {
my($base,$exp) = @_;
die "Exponent '$exp' must be an integer!" if $exp != int($exp);
return 1 if $exp == 0;
($base, $exp) = (1/$base, -$exp) if $exp < 0;
my $c = 1;
while ($exp > 1) {
$c *= $base if $exp % 2;
$base *= $base;
$exp >>= 1;
}
$base * $c;
}

View file

@ -0,0 +1,2 @@
:- arithmetic_function((^^)/2).
:- op(200, xfy, user:(^^)).

View file

@ -0,0 +1,24 @@
%% ^^/3
%
% True if Power is Base ^ Exp.
^^(Base, Exp, Power) :-
( Exp < 0 -> Power is 1 / (Base ^^ (Exp * -1)) % If exponent is negative, then ...
; Exp > 0 -> length(Powers, Exp), % If exponent is positive, then
foldl( exp_folder(Base), Powers, 1, Power ) % Powers is a list of free variables with length Exp
% and Power is Powers folded with exp_folder/4
; Power = 1 % otherwise Exp must be 0, so
).
%% exp_folder/4
%
% True when Power is the product of Base and Powers.
%
% This predicate is designed to work with foldl and a list of free variables.
% It passes the result of each evaluation to the next application through its
% fourth argument, instantiating the elements of Powers to each successive Power of the Base.
exp_folder(Base, Power, Powers, Power) :-
Power is Base * Powers.

View file

@ -0,0 +1,11 @@
?- X is 2 ^^ 3.
X = 8.
?- X is 2 ^^ -3.
X = 0.125.
?- X is 2.5 ^^ -3.
X = 0.064.
?- X is 2.5 ^^ 3.
X = 15.625.

View file

@ -0,0 +1,16 @@
exp_recursive(Base, NegExp, NegPower) :-
NegExp < 0,
Exp is NegExp * -1,
exp_recursive_(Base, Exp, Base, Power),
NegPower is 1 / Power.
exp_recursive(Base, Exp, Power) :-
Exp > 0,
exp_recursive_(Base, Exp, Base, Power).
exp_recursive(_, 0, 1).
exp_recursive_(_, 1, Power, Power).
exp_recursive_(Base, Exp, Acc, Power) :-
Exp > 1,
NewAcc is Base * Acc,
NewExp is Exp - 1,
exp_recursive_(Base, NewExp, NewAcc, Power).

View file

@ -1,44 +1,32 @@
const func float: fltIPow (in var float: base, in var integer: exponent) is func
result
var float: result is 0.0;
var float: power is 1.0;
local
var boolean: neg_exp is FALSE;
var integer: stop is 0;
begin
if base = 0.0 then
if exponent < 0 then
result := Infinity;
elsif exponent = 0 then
result := 1.0;
else
result := 0.0;
power := Infinity;
elsif exponent > 0 then
power := 0.0;
end if;
else
if exponent < 0 then
exponent := -exponent;
neg_exp := TRUE;
stop := -1;
end if;
# In the twos complement representation the most
# negative number is the only one where both the
# number and its negation are negative. When the
# exponent is proven to be to the most negative
# number fltIPow returns 0.0 .
if exponent >= 0 then
if odd(exponent) then
power := base;
end if;
exponent >>:= 1;
while exponent <> stop do
base *:= base;
if odd(exponent) then
result := base;
else
result := 1.0;
power *:= base;
end if;
exponent >>:= 1;
while exponent <> 0 do
base *:= base;
if odd(exponent) then
result *:= base;
end if;
exponent >>:= 1;
end while;
if neg_exp then
result := 1.0 / result;
end if;
end while;
if stop = -1 then
power := 1.0 / power;
end if;
end if;
end func;