This commit is contained in:
Ingy döt Net 2013-04-10 16:57:12 -07:00
parent 518da4a923
commit 764da6cbbb
6144 changed files with 83610 additions and 11 deletions

View file

@ -0,0 +1,4 @@
Most all programming languages have a built-in implementation of exponentiation.
Re-implement integer exponentiation for both int<sup>int</sup> and float<sup>int</sup> as both a procedure, and an operator (if your language supports operator definition).
If the language supports operator (or procedure) overloading, then an overloaded form should be provided for both int<sup>int</sup> and float<sup>int</sup> variants.

View file

@ -0,0 +1,2 @@
---
note: Arithmetic operations

View file

@ -0,0 +1,61 @@
main:(
INT two=2, thirty=30; # test constants #
PROC VOID undefined;
# First implement exponentiation using a rather slow but sure FOR loop #
PROC int pow = (INT base, exponent)INT: ( # PROC cannot be over loaded #
IF exponent<0 THEN undefined FI;
INT out:=( exponent=0 | 1 | base );
FROM 2 TO exponent DO out*:=base OD;
out
);
printf(($" One Gibi-unit is: int pow("g(0)","g(0)")="g(0)" - (cost: "g(0)
" INT multiplications)"l$,two, thirty, int pow(two,thirty),thirty-1));
# implement exponentiation using a faster binary technique and WHILE LOOP #
OP ** = (INT base, exponent)INT: (
BITS binary exponent:=BIN exponent ; # do exponent arithmetic in binary #
INT out := IF bits width ELEM binary exponent THEN base ELSE 1 FI;
INT sq := IF exponent < 0 THEN undefined; ~ ELSE base FI;
WHILE
binary exponent := binary exponent SHR 1;
binary exponent /= BIN 0
DO
sq *:= sq;
IF bits width ELEM binary exponent THEN out *:= sq FI
OD;
out
);
printf(($" One Gibi-unit is: "g(0)"**"g(0)"="g(0)" - (cost: "g(0)
" INT multiplications)"l$,two, thirty, two ** thirty,8));
OP ** = (REAL in base, INT in exponent)REAL: ( # ** INT Operator can be overloaded #
REAL base := ( in exponent<0 | 1/in base | in base);
INT exponent := ABS in exponent;
BITS binary exponent:=BIN exponent ; # do exponent arithmetic in binary #
REAL out := IF bits width ELEM binary exponent THEN base ELSE 1 FI;
REAL sq := base;
WHILE
binary exponent := binary exponent SHR 1;
binary exponent /= BIN 0
DO
sq *:= sq;
IF bits width ELEM binary exponent THEN out *:= sq FI
OD;
out
);
printf(($" One Gibi-unit is: "g(0,1)"**"g(0)"="g(0,1)" - (cost: "g(0)
" REAL multiplications)"l$, 2.0, thirty, 2.0 ** thirty,8));
OP ** = (REAL base, REAL exponent)REAL: ( # ** REAL Operator can be overloaded #
exp(ln(base)*exponent)
);
printf(($" One Gibi-unit is: "g(0,1)"**"g(0,1)"="g(0,1)" - (cost: "
"depends on precision)"l$, 2.0, 30.0, 2.0 ** 30.0))
)

View file

@ -0,0 +1,50 @@
main:(
INT two=2, thirty=30; # test constants #
PROC VOID undefined;
# First implement exponentiation using a rather slow but sure FOR loop #
PROC int pow = (INT base, exponent)INT: ( # PROC cannot be over loaded #
IF exponent<0 THEN undefined FI;
INT out:=( exponent=0 | 1 | base );
FROM 2 TO exponent DO out*:=base OD;
out
);
printf(($" One Gibi-unit is: int pow("g(0)","g(0)")="g(0)" - (cost: "g(0)
" INT multiplications)"l$,two, thirty, int pow(two,thirty),thirty-1));
# implement exponentiation using a faster binary technique and WHILE LOOP #
OP ** = (INT base, exponent)INT:
IF base = 0 THEN 0 ELIF base = 1 THEN 1
ELIF exponent = 0 THEN 1 ELIF exponent = 1 THEN base
ELIF ODD exponent THEN
(base*base) ** (exponent OVER 2) * base
ELSE
(base*base) ** (exponent OVER 2)
FI;
printf(($" One Gibi-unit is: "g(0)"**"g(0)"="g(0)" - (cost: "g(0)
" INT multiplications)"l$,two, thirty, two ** thirty,8));
OP ** = (REAL in base, INT in exponent)REAL: ( # ** INT Operator can be overloaded #
REAL base := ( in exponent<0 | 1/in base | in base);
INT exponent := ABS in exponent;
IF base = 0 THEN 0 ELIF base = 1 THEN 1
ELIF exponent = 0 THEN 1 ELIF exponent = 1 THEN base
ELIF ODD exponent THEN
(base*base) ** (exponent OVER 2) * base
ELSE
(base*base) ** (exponent OVER 2)
FI
);
printf(($" One Gibi-unit is: "g(0,1)"**"g(0)"="g(0,1)" - (cost: "g(0)
" REAL multiplications)"l$, 2.0, thirty, 2.0 ** thirty,8));
OP ** = (REAL base, REAL exponent)REAL: ( # ** REAL Operator can be overloaded #
exp(ln(base)*exponent)
);
printf(($" One Gibi-unit is: "g(0,1)"**"g(0,1)"="g(0,1)" - (cost: "
"depends on precision)"l$, 2.0, 30.0, 2.0 ** 30.0))
)

View file

@ -0,0 +1,7 @@
$ awk 'function pow(x,n){r=1;for(i=0;i<n;i++)r=r*x;return r}{print pow($1,$2)}'
2.5 2
6.25
10 6
1000000
3 0
1

View file

@ -0,0 +1,15 @@
package Integer_Exponentiation is
-- int^int
procedure Exponentiate (Argument : in Integer;
Exponent : in Natural;
Result : out Integer);
function "**" (Left : Integer;
Right : Natural) return Integer;
-- real^int
procedure Exponentiate (Argument : in Float;
Exponent : in Integer;
Result : out Float);
function "**" (Left : Float;
Right : Integer) return Float;
end Integer_Exponentiation;

View file

@ -0,0 +1,19 @@
with Ada.Float_Text_IO, Ada.Integer_Text_IO, Ada.Text_IO;
with Integer_Exponentiation;
procedure Test_Integer_Exponentiation is
use Ada.Float_Text_IO, Ada.Integer_Text_IO, Ada.Text_IO;
use Integer_Exponentiation;
R : Float;
I : Integer;
begin
Exponentiate (Argument => 2.5, Exponent => 3, Result => R);
Put ("2.5 ^ 3 = ");
Put (R, Fore => 2, Aft => 4, Exp => 0);
New_Line;
Exponentiate (Argument => -12, Exponent => 3, Result => I);
Put ("-12 ^ 3 = ");
Put (I, Width => 7);
New_Line;
end Test_Integer_Exponentiation;

View file

@ -0,0 +1,49 @@
package body Integer_Exponentiation is
-- int^int
procedure Exponentiate (Argument : in Integer;
Exponent : in Natural;
Result : out Integer) is
begin
Result := 1;
for Counter in 1 .. Exponent loop
Result := Result * Argument;
end loop;
end Exponentiate;
function "**" (Left : Integer;
Right : Natural) return Integer is
Result : Integer;
begin
Exponentiate (Argument => Left,
Exponent => Right,
Result => Result);
return Result;
end "**";
-- real^int
procedure Exponentiate (Argument : in Float;
Exponent : in Integer;
Result : out Float) is
begin
Result := 1.0;
if Exponent < 0 then
for Counter in Exponent .. -1 loop
Result := Result / Argument;
end loop;
else
for Counter in 1 .. Exponent loop
Result := Result * Argument;
end loop;
end if;
end Exponentiate;
function "**" (Left : Float;
Right : Integer) return Float is
Result : Float;
begin
Exponentiate (Argument => Left,
Exponent => Right,
Result => Result);
return Result;
end "**";
end Integer_Exponentiation;

View file

@ -0,0 +1,9 @@
MsgBox % Pow(5,3)
MsgBox % Pow(2.5,4)
Pow(x, n){
r:=1
loop %n%
r *= x
return r
}

View file

@ -0,0 +1,39 @@
DECLARE FUNCTION powL& (x AS INTEGER, y AS INTEGER)
DECLARE FUNCTION powS# (x AS SINGLE, y AS INTEGER)
DIM x AS INTEGER, y AS INTEGER
DIM a AS SINGLE
RANDOMIZE TIMER
a = RND * 10
x = INT(RND * 10)
y = INT(RND * 10)
PRINT x, y, powL&(x, y)
PRINT a, y, powS#(a, y)
FUNCTION powL& (x AS INTEGER, y AS INTEGER)
DIM n AS INTEGER, m AS LONG
IF x <> 0 THEN
m = 1
IF SGN(y) > 0 THEN
FOR n = 1 TO y
m = m * x
NEXT
END IF
END IF
powL& = m
END FUNCTION
FUNCTION powS# (x AS SINGLE, y AS INTEGER)
DIM n AS INTEGER, m AS DOUBLE
IF x <> 0 THEN
m = 1
IF y <> 0 THEN
FOR n = 1 TO y
m = m * x
NEXT
IF y < 0 THEN m = 1# / m
END IF
END IF
powS# = m
END FUNCTION

View file

@ -0,0 +1,23 @@
PRINT "11^5 = " ; FNipow(11, 5)
PRINT "PI^3 = " ; FNfpow(PI, 3)
END
DEF FNipow(A%, B%)
LOCAL I%, P%
P% = 1
FOR I% = 1 TO 32
P% *= P%
IF B% < 0 THEN P% *= A%
B% = B% << 1
NEXT
= P%
DEF FNfpow(A, B%)
LOCAL I%, P
P = 1
FOR I% = 1 TO 32
P *= P
IF B% < 0 THEN P *= A
B% = B% << 1
NEXT
= P

View file

@ -0,0 +1,13 @@
#Procedure
exp = { base, exp |
1.to(exp).reduce 1, { m, n | m = m * base }
}
#Numbers are weird
1.parent.^ = { rhs |
num = my
1.to(rhs).reduce 1 { m, n | m = m * num }
}
p exp 2 5 #Prints 32
p 2 ^ 5 #Prints 32

View file

@ -0,0 +1,32 @@
template<typename Number>
Number power(Number base, int exponent)
{
int zerodir;
Number factor;
if (exponent < 0)
{
zerodir = 1;
factor = Number(1)/base;
}
else
{
zerodir = -1;
factor = base;
}
Number result(1);
while (exponent != 0)
{
if (exponent % 2 != 0)
{
result *= factor;
exponent += zerodir;
}
else
{
factor *= factor;
exponent /= 2;
}
}
return result;
}

View file

@ -0,0 +1,43 @@
#include <stdio.h>
#include <assert.h>
int ipow(int base, int exp)
{
int pow = base;
int v = 1;
if (exp < 0) {
assert (base != 0); /* divide by zero */
return (base*base != 1)? 0: (exp&1)? base : 1;
}
while(exp > 0 )
{
if (exp & 1) v *= pow;
pow *= pow;
exp >>= 1;
}
return v;
}
double dpow(double base, int exp)
{
double v=1.0;
double pow = (exp <0)? 1.0/base : base;
if (exp < 0) exp = - exp;
while(exp > 0 )
{
if (exp & 1) v *= pow;
pow *= pow;
exp >>= 1;
}
return v;
}
int main()
{
printf("2^6 = %d\n", (int)ipow(2,6));
printf("2^-6 = %lf\n", ipow(2,-6));
printf("2.71^6 = %lf\n", dpow(2.71,6));
printf("2.71^-6 = %lf\n", dpow(2.71,-6));
}

View file

@ -0,0 +1 @@
(defn ** [x n] (reduce * (repeat n x)))

View file

@ -0,0 +1,4 @@
(defun my-expt-do (a b)
(do ((x 1 (* x a))
(y 0 (+ y 1)))
((= y b) x)))

View file

@ -0,0 +1,4 @@
(defun my-expt-rec (a b)
(cond
((= b 0) 1)
(t (* a (my-expt-rec a (- b 1))))))

View file

@ -0,0 +1,4 @@
(defun ^ (a b)
(do ((x 1 (* x a))
(y 0 (+ y 1)))
((= y b) x)))

View file

@ -0,0 +1,47 @@
import std.stdio, std.conv;
struct Number(T) {
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 {
if (exponent < 0)
assert (x != 0, "Division by zero");
} body {
debug puts("opBinary ^^");
int zerodir;
T factor;
if (exponent < 0) {
zerodir = +1;
factor = (cast(T)1) / x;
} else {
zerodir = -1;
factor = x;
}
T result = 1;
int e = exponent;
while (e != 0)
if (e % 2 != 0) {
result *= factor;
e += zerodir;
} else {
factor *= factor;
e /= 2;
}
return Number(result);
}
}
void main() {
alias Double = Number!double;
writeln(Double(2.5) ^^ 5);
alias Int = Number!int;
writeln(Int(3) ^^ 3);
writeln(Int(0) ^^ -2); // Division by zero.
}

View file

@ -0,0 +1,11 @@
def power(base, exponent :int) {
var r := base
if (exponent < 0) {
for _ in exponent..0 { r /= base }
} else if (exponent <=> 0) {
return 1
} else {
for _ in 2..exponent { r *= base }
}
return r
}

View file

@ -0,0 +1,19 @@
% -spec attribute is for documentation and dialyzer static analysis purposes only.
% It does not constrain the function like a guard (when ... ).
-spec exp_int(X :: integer(), N :: non_neg_integer()) -> integer().
% X ^ 0
exp_int(X, 0) when is_integer(X) -> % is_integer guard is required, otherwise X would match anything.
1;
% X ^ odd
exp_int(X, N) when is_integer(X), N >= 1, N rem 2 == 1 ->
Part = exp_int(X, (N-1) div 2),
X * Part * Part;
% X ^ even
exp_int(X, N) when is_integer(X), N >= 2, N rem 2 == 0 ->
Part = exp_int(X, N div 2),
Part * Part.
% X ^ negative is excluded because it would return float.

View file

@ -0,0 +1,21 @@
% -spec attribute is for documentation and dialyzer static analysis purposes only.
% It does not constrain the function like a guard (when ... ).
-spec exp_float(X :: float(), N :: integer()) -> float().
% X ^ 0
exp_float(X, 0) when is_float(X) -> % is_float guard is required, otherwise X would match anything.
1.0;
% X ^ negative
exp_float(X, N) when is_float(X), N < 0 ->
1.0 / exp_float(X, -N);
% X ^ even
exp_float(X, N) when is_float(X), N >= 1, N rem 2 == 1 ->
Part = exp_float(X, (N-1) div 2),
X * Part * Part;
% X ^ odd
exp_float(X, N) when is_float(X), N >= 2, N rem 2 == 0 ->
Part = exp_float(X, N div 2),
Part * Part.

View file

@ -0,0 +1,2 @@
: ** ( n m -- n^m )
1 swap 0 ?do over * loop nip ;

View file

@ -0,0 +1,8 @@
: f**n ( f n -- f^n )
dup 0= if
drop fdrop 1e
else dup 1 and if
1- fdup recurse f*
else
2/ fdup f* recurse
then then ;

View file

@ -0,0 +1,51 @@
MODULE Exp_Mod
IMPLICIT NONE
INTERFACE OPERATOR (.pow.) ! Using ** instead would overload the standard exponentiation operator
MODULE PROCEDURE Intexp, Realexp
END INTERFACE
CONTAINS
FUNCTION Intexp (base, exponent)
INTEGER :: Intexp
INTEGER, INTENT(IN) :: base, exponent
INTEGER :: i
IF (exponent < 0) THEN
IF (base == 1) THEN
Intexp = 1
ELSE
Intexp = 0
END IF
RETURN
END IF
Intexp = 1
DO i = 1, exponent
Intexp = Intexp * base
END DO
END FUNCTION IntExp
FUNCTION Realexp (base, exponent)
REAL :: Realexp
REAL, INTENT(IN) :: base
INTEGER, INTENT(IN) :: exponent
INTEGER :: i
Realexp = 1.0
IF (exponent < 0) THEN
DO i = exponent, -1
Realexp = Realexp / base
END DO
ELSE
DO i = 1, exponent
Realexp = Realexp * base
END DO
END IF
END FUNCTION RealExp
END MODULE Exp_Mod
PROGRAM EXAMPLE
USE Exp_Mod
WRITE(*,*) 2.pow.30, 2.0.pow.30
END PROGRAM EXAMPLE

View file

@ -0,0 +1,77 @@
package main
import (
"errors"
"fmt"
)
func expI(b, p int) (int, error) {
if p < 0 {
return 0, errors.New("negative power not allowed")
}
r := 1
for i := 1; i <= p; i++ {
r *= b
}
return r, nil
}
func expF(b float32, p int) float32 {
var neg bool
if p < 0 {
neg = true
p = -p
}
r := float32(1)
for pow := b; p > 0; pow *= pow {
if p&1 == 1 {
r *= pow
}
p >>= 1
}
if neg {
r = 1 / r
}
return r
}
func main() {
ti := func(b, p int) {
fmt.Printf("%d^%d: ", b, p)
e, err := expI(b, p)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(e)
}
}
fmt.Println("expI tests")
ti(2, 10)
ti(2, -10)
ti(-2, 10)
ti(-2, 11)
ti(11, 0)
fmt.Println("overflow undetected")
ti(10, 10)
tf := func(b float32, p int) {
fmt.Printf("%g^%d: %g\n", b, p, expF(b, p))
}
fmt.Println("\nexpF tests:")
tf(2, 10)
tf(2, -10)
tf(-2, 10)
tf(-2, 11)
tf(11, 0)
fmt.Println("disallowed in expI, allowed here")
tf(0, -1)
fmt.Println("other interesting cases for 32 bit float type")
tf(10, 39)
tf(10, -39)
tf(-10, 39)
}

View file

@ -0,0 +1,8 @@
(^) :: (Num a, Integral b) => a -> b -> a
_ ^ 0 = 1
x ^ n | n > 0 = f x (n-1) x where
f _ 0 y = y
f a d y = g a d where
g b i | even i = g (b*b) (i `quot` 2)
| otherwise = f b (i-1) (b*y)
_ ^ _ = error "Prelude.^: negative exponent"

View file

@ -0,0 +1,2 @@
(^^) :: (Fractional a, Integral b) => a -> b -> a
x ^^ n = if n >= 0 then x^n else recip (x^(negate n))

View file

@ -0,0 +1,2 @@
(**) :: Floating a => a -> a -> a
x ** y = exp (log x * y)

View file

@ -0,0 +1,14 @@
public class Exp{
public static void main(String[] args){
System.out.println(pow(2,30));
System.out.println(pow(2.0,30)); //tests
System.out.println(pow(2.0,-2));
}
public static double pow(double base, int exp){
if(exp < 0) return 1 / pow(base, -exp);
double ans = 1.0;
for(;exp > 0;--exp) ans *= base;
return ans;
}
}

View file

@ -0,0 +1,12 @@
function pow(base, exp) {
if (exp != Math.floor(exp))
throw "exponent must be an integer";
if (exp < 0)
return 1 / pow(base, -exp);
var ans = 1;
while (exp > 0) {
ans *= base;
exp--;
}
return ans;
}

View file

@ -0,0 +1,26 @@
number = {}
function number.pow( a, b )
local ret = 1
if b >= 0 then
for i = 1, b do
ret = ret * a.val
end
else
for i = b, -1 do
ret = ret / a.val
end
end
return ret
end
function number.New( v )
local num = { val = v }
local mt = { __pow = number.pow }
setmetatable( num, mt )
return num
end
x = number.New( 5 )
print( x^2 ) --> 25
print( number.pow( x, -4 ) ) --> 0.016

View file

@ -0,0 +1,26 @@
#!/usr/bin/perl -w
use strict ;
sub expon {
my ( $base , $expo ) = @_ ;
if ( $expo == 0 ) {
return 1 ;
}
elsif ( $expo == 1 ) {
return $base ;
}
elsif ( $expo > 1 ) {
my $prod = 1 ;
foreach my $n ( 0..($expo - 1) ) {
$prod *= $base ;
}
return $prod ;
}
elsif ( $expo < 0 ) {
return 1 / ( expon ( $base , -$expo ) ) ;
}
}
print "3 to the power of 10 as a function is " . expon( 3 , 10 ) . " !\n" ;
print "3 to the power of 10 as a builtin is " . 3**10 . " !\n" ;
print "5.5 to the power of -3 as a function is " . expon( 5.5 , -3 ) . " !\n" ;
print "5.5 to the power of -3 as a builtin is " . 5.5**-3 . " !\n" ;

View file

@ -0,0 +1,8 @@
(de ** (X N) # N th power of X
(let Y 1
(loop
(when (bit? 1 N)
(setq Y (* Y X)) )
(T (=0 (setq N (>> 1 N)))
Y )
(setq X (* X X)) ) ) )

View file

@ -0,0 +1,22 @@
>>> import operator
>>> class num(int):
def __pow__(self, b):
print "Empowered"
return operator.__pow__(self+0, b)
>>> x = num(3)
>>> x**2
Empowered
9
>>> class num(float):
def __pow__(self, b):
print "Empowered"
return operator.__pow__(self+0, b)
>>> x = num(2.5)
>>> x**2
Empowered
6.25
>>>

View file

@ -0,0 +1,12 @@
# Method
pow <- function(x, y)
{
x <- as.numeric(x)
y <- as.integer(y)
prod(rep(x, y))
}
#Operator
"%pow%" <- function(x,y) pow(x,y)
pow(3, 4) # 81
2.5 %pow% 2 # 6.25

View file

@ -0,0 +1,38 @@
/*REXX program to show various (integer) exponentations. */
say center('digits='digits(),79,'')
say '17**65 is:'
say 17**65
numeric digits 100; say; say center('digits='digits(),79,'')
say '17**65 is:'
say 17**65
numeric digits 10; say; say center('digits='digits(),79,'')
say '2 ** -10 is:'
say 2 ** -10
numeric digits 30; say; say center('digits='digits(),79,'')
say '-3.1415926535897932384626433 ** 3 is:'
say -3.1415926535897932384626433 ** 3
numeric digits 1000; say; say center('digits='digits(),79,'')
say '2 ** 1000 is:'
say 2 ** 1000
numeric digits 60; say; say center('digits='digits(),79,'')
say 'ipow(5,70) is:'
say ipow(5,70)
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────ERRIPOW subroutine──────────────────*/
errIpow: say; say '***error!***'; say; say arg(1); say; say; exit 13
/*──────────────────────────────────IPOW subroutine─────────────────────*/
ipow: procedure; parse arg x 1 _,p
if arg()<2 then call erripow 'not enough arguments specified'
if arg()>2 then call erripow 'too many arguments specified'
if \datatype(_,'N') then call erripow "1st arg isn't numeric:" _
if \datatype(p,'W') then call erripow "2nd arg isn't an integer:" p
if p=0 then return 1
pa=abs(p)
do pa-1; _=_*x; end
if p<0 then _=1/_
return _

View file

@ -0,0 +1,16 @@
class Numeric
def pow(m)
raise TypeError, "exponent must be an integer: #{m}" unless m.is_a? Integer
puts "pow!!"
# below requires Ruby 1.8.7
Array.new(m, self).reduce(1, :*)
# for earlier versions of Ruby
#Array.new(m, self).inject(1) { |res, n| res * n }
end
end
p 5.pow(3)
p 5.5.pow(3)
p 5.pow(3.1)

View file

@ -0,0 +1,5 @@
class Numeric
def **(m)
pow(m)
end
end

View file

@ -0,0 +1,22 @@
class Fixnum
def **(m)
print "Fixnum "
pow(m)
end
end
class Bignum
def **(m)
print "Bignum "
pow(m)
end
end
class Float
def **(m)
print "Float "
pow(m)
end
end
p i=2**64
p i ** 2
p 2.2 ** 3

View file

@ -0,0 +1,43 @@
object Exponentiation {
import scala.annotation.tailrec
@tailrec def powI[N](n: N, exponent: Int)(implicit num: Integral[N]): N = {
import num._
exponent match {
case 0 => one
case _ if exponent % 2 == 0 => powI((n * n), (exponent / 2))
case _ => powI(n, (exponent - 1)) * n
}
}
@tailrec def powF[N](n: N, exponent: Int)(implicit num: Fractional[N]): N = {
import num._
exponent match {
case 0 => one
case _ if exponent < 0 => one / powF(n, exponent.abs)
case _ if exponent % 2 == 0 => powF((n * n), (exponent / 2))
case _ => powF(n, (exponent - 1)) * n
}
}
class ExponentI[N : Integral](n: N) {
def \u2191(exponent: Int): N = powI(n, exponent)
}
class ExponentF[N : Fractional](n: N) {
def \u2191(exponent: Int): N = powF(n, exponent)
}
object ExponentI {
implicit def toExponentI[N : Integral](n: N): ExponentI[N] = new ExponentI(n)
}
object ExponentF {
implicit def toExponentF[N : Fractional](n: N): ExponentF[N] = new ExponentF(n)
}
object Exponents {
implicit def toExponent(n: Int): ExponentI[Int] = new ExponentI(n)
implicit def toExponent(n: Double): ExponentF[Double] = new ExponentF(n)
}
}

View file

@ -0,0 +1,7 @@
@tailrec def powI[N](n: N, exponent: Int, acc:Int=1)(implicit num: Integral[N]): N = {
exponent match {
case 0 => acc
case _ if exponent % 2 == 0 => powI(n * n, exponent / 2, acc)
case _ => powI(n, (exponent - 1), acc*n)
}
}

View file

@ -0,0 +1,15 @@
(define (^ base exponent)
(define (*^ exponent acc)
(if (= exponent 0)
acc
(*^ (- exponent 1) (* acc base))))
(*^ exponent 1))
(display (^ 2 3))
(newline)
(display (^ (/ 1 2) 3))
(newline)
(display (^ 0.5 3))
(newline)
(display (^ 2+i 3))
(newline)

View file

@ -0,0 +1,16 @@
Number extend [
** anInt [
| r |
( anInt isInteger )
ifFalse:
[ '** works fine only for integer powers'
displayOn: stderr . Character nl displayOn: stderr ].
r := 1.
1 to: anInt do: [ :i | r := ( r * self ) ].
^r
]
].
( 2.5 ** 3 ) displayNl.
( 2 ** 10 ) displayNl.
( 3/7 ** 3 ) displayNl.

View file

@ -0,0 +1,10 @@
package require Tcl 8.5
proc tcl::mathfunc::mypow {a b} {
if { ! [string is int -strict $b]} {error "exponent must be an integer"}
set res 1
for {set i 1} {$i <= $b} {incr i} {set res [expr {$res * $a}]}
return $res
}
expr {mypow(3, 3)} ;# ==> 27
expr {mypow(3.5, 3)} ;# ==> 42.875
expr {mypow(3.5, 3.2)} ;# ==> exponent must be an integer