implement pi, e and some operations

This commit is contained in:
Gwenhael Le Moine 2021-12-02 15:33:22 +01:00
parent 803036b89e
commit ca6b79a8ad
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
6 changed files with 200 additions and 11 deletions

View file

@ -9,6 +9,8 @@ require_relative './language/stack'
require_relative './language/string'
require_relative './language/test'
require_relative './language/time-date'
require_relative './language/trig'
require_relative './language/logs'
module Rpl
module Core

View file

@ -50,18 +50,18 @@ module Rpl
add( 'sign', proc { |stack| Rpl::Core.sign( stack ) } )
# OPERATIONS ON REALS
add( '%', proc { |stack| Rpl::Core.__todo( stack ) } ) # percent
add( '%CH', proc { |stack| Rpl::Core.__todo( stack ) } ) # inverse percent
add( 'mod', proc { |stack| Rpl::Core.__todo( stack ) } ) # modulo
add( 'fact', proc { |stack| Rpl::Core.__todo( stack ) } ) # n! for integer n or Gamma(x+1) for fractional x
add( '%', proc { |stack| Rpl::Core.percent( stack ) } )
add( '%CH', proc { |stack| Rpl::Core.inverse_percent( stack ) } )
add( 'mod', proc { |stack| Rpl::Core.mod( stack ) } )
add( 'fact', proc { |stack| Rpl::Core.fact( stack ) } )
add( 'mant', proc { |stack| Rpl::Core.__todo( stack ) } ) # mantissa of a real number
add( 'xpon', proc { |stack| Rpl::Core.__todo( stack ) } ) # exponant of a real number
add( 'floor', proc { |stack| Rpl::Core.__todo( stack ) } ) # largest number <=
add( 'ceil', proc { |stack| Rpl::Core.__todo( stack ) } ) # smallest number >=
add( 'floor', proc { |stack| Rpl::Core.floor( stack ) } )
add( 'ceil', proc { |stack| Rpl::Core.ceil( stack ) } )
add( 'ip', proc { |stack| Rpl::Core.__todo( stack ) } ) # integer part
add( 'fp', proc { |stack| Rpl::Core.__todo( stack ) } ) # fractional part
add( 'min', proc { |stack| Rpl::Core.__todo( stack ) } ) # min of 2 real numbers
add( 'max', proc { |stack| Rpl::Core.__todo( stack ) } ) # max of 2 real numbers
add( 'min', proc { |stack| Rpl::Core.min( stack ) } )
add( 'max', proc { |stack| Rpl::Core.max( stack ) } )
# OPERATIONS ON COMPLEXES
add( 're', proc { |stack| Rpl::Core.__todo( stack ) } ) # complex real part
@ -133,7 +133,7 @@ module Rpl
# STORE
add( 'sto', proc { |stack| Rpl::Core.__todo( stack ) } ) # store a variable. ex: 1 'name' sto
add( '▶', proc { |stack| Rpl::Core.__todo( stack ) } ) # alias
add( '▶', proc { |stack| Rpl::Core.sto( stack ) } ) # alias
add( 'rcl', proc { |stack| Rpl::Core.__todo( stack ) } ) # recall a variable. ex: 'name' rcl
add( 'purge', proc { |stack| Rpl::Core.__todo( stack ) } ) # delete a variable. ex: 'name' purge
add( 'vars', proc { |stack| Rpl::Core.__todo( stack ) } ) # list all variables
@ -152,7 +152,8 @@ module Rpl
add( '→', proc { |stack| Rpl::Core.__todo( stack ) } ) # alias
# TRIG ON REALS AND COMPLEXES
add( 'pi', proc { |stack| Rpl::Core.__todo( stack ) } ) # pi constant
add( 'pi', proc { |stack| Rpl::Core.pi( stack ) } )
add( '𝛑', proc { |stack| Rpl::Core.pi( stack ) } ) # alias
add( 'sin', proc { |stack| Rpl::Core.__todo( stack ) } ) # sinus
add( 'asin', proc { |stack| Rpl::Core.__todo( stack ) } ) # arg sinus
add( 'cos', proc { |stack| Rpl::Core.__todo( stack ) } ) # cosinus
@ -165,7 +166,8 @@ module Rpl
add( 'r→d', proc { |stack| Rpl::Core.__todo( stack ) } ) # alias
# LOGS ON REALS AND COMPLEXES
add( 'e', proc { |stack| Rpl::Core.__todo( stack ) } ) # Euler constant
add( 'e', proc { |stack| Rpl::Core.e( stack ) } )
add( 'ℇ', proc { |stack| Rpl::Core.e( stack ) } ) # alias
add( 'ln', proc { |stack| Rpl::Core.__todo( stack ) } ) # logarithm base e
add( 'lnp1', proc { |stack| Rpl::Core.__todo( stack ) } ) # ln(1+x) which is useful when x is close to 0
add( 'exp', proc { |stack| Rpl::Core.__todo( stack ) } ) # exponential

13
lib/language/logs.rb Normal file
View file

@ -0,0 +1,13 @@
module Rpl
module Core
module_function
# Euler constant
def e( stack )
stack << { type: :numeric,
base: 10,
value: BigMath.E( Rpl::Core.precision ) }
stack
end
end
end

View file

@ -152,5 +152,91 @@ module Rpl
stack << { type: :numeric, base: 10,
value: value }
end
# OPERATIONS ON REALS
# percent
def percent( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
stack << { type: :numeric,
base: 10,
value: args[0][:value] * ( args[1][:value] / 100.0 ) }
stack
end
# inverse percent
def inverse_percent( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
stack << { type: :numeric,
base: 10,
value: 100.0 * ( args[0][:value] / args[1][:value] ) }
stack
end
# modulo
def mod( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
stack << { type: :numeric,
base: 10,
value: args[1][:value] % args[0][:value] }
stack
end
# n! for integer n or Gamma(x+1) for fractional x
def fact( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric]] )
stack << { type: :numeric,
base: 10,
value: Math.gamma( args[0][:value] ) }
stack
end
# largest number <=
def floor( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric]] )
stack << { type: :numeric,
base: 10,
value: args[0][:value].floor }
stack
end
# smallest number >=
def ceil( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric]] )
stack << { type: :numeric,
base: 10,
value: args[0][:value].ceil }
stack
end
# min of 2 real numbers
def min( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
stack << ( args[0][:value] < args[1][:value] ? args[0] : args[1] )
stack
end
# max of 2 real numbers
def max( stack )
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
stack << ( args[0][:value] > args[1][:value] ? args[0] : args[1] )
stack
end
end
end

13
lib/language/trig.rb Normal file
View file

@ -0,0 +1,13 @@
module Rpl
module Core
module_function
# pi constant
def pi( stack )
stack << { type: :numeric,
base: 10,
value: BigMath.PI( Rpl::Core.precision ) }
stack
end
end
end

View file

@ -177,4 +177,77 @@ class TesttLanguageOperations < Test::Unit::TestCase
assert_equal [{ value: 0, type: :numeric, base: 10 }],
stack
end
def test_percent
stack = Rpl::Core.percent [{ value: 2, type: :numeric, base: 10 },
{ value: 33, type: :numeric, base: 10 }]
assert_equal [{ value: 0.66, type: :numeric, base: 10 }],
stack
end
def test_inverse_percent
stack = Rpl::Core.inverse_percent [{ value: 2, type: :numeric, base: 10 },
{ value: 0.66, type: :numeric, base: 10 }]
assert_equal [{ value: 33, type: :numeric, base: 10 }],
stack
end
def test_mod
stack = Rpl::Core.mod [{ value: 9, type: :numeric, base: 10 },
{ value: 4, type: :numeric, base: 10 }]
assert_equal [{ value: 1, type: :numeric, base: 10 }],
stack
end
def test_fact
stack = Rpl::Core.fact [{ value: 5, type: :numeric, base: 10 }]
assert_equal [{ value: 24, type: :numeric, base: 10 }],
stack
end
def test_floor
stack = Rpl::Core.floor [{ value: 5.23, type: :numeric, base: 10 }]
assert_equal [{ value: 5, type: :numeric, base: 10 }],
stack
end
def test_ceil
stack = Rpl::Core.ceil [{ value: 5.23, type: :numeric, base: 10 }]
assert_equal [{ value: 6, type: :numeric, base: 10 }],
stack
end
def test_min
stack = Rpl::Core.min [{ value: 1, type: :numeric, base: 10 },
{ value: 2, type: :numeric, base: 10 }]
assert_equal [{ value: 1, type: :numeric, base: 10 }],
stack
stack = Rpl::Core.min [{ value: 2, type: :numeric, base: 10 },
{ value: 1, type: :numeric, base: 10 }]
assert_equal [{ value: 1, type: :numeric, base: 10 }],
stack
end
def test_max
stack = Rpl::Core.max [{ value: 1, type: :numeric, base: 10 },
{ value: 2, type: :numeric, base: 10 }]
assert_equal [{ value: 2, type: :numeric, base: 10 }],
stack
stack = Rpl::Core.max [{ value: 2, type: :numeric, base: 10 },
{ value: 1, type: :numeric, base: 10 }]
assert_equal [{ value: 2, type: :numeric, base: 10 }],
stack
end
end