Moved eel and eapml under the contrib folder.
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
note
|
||||
description: "Convert between character codes and numbers ignoring case"
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "There can be no freedom without freedom to fail. - Eric Hoffer (1902-1983), The Ordeal of Change, 1964"
|
||||
|
||||
class
|
||||
CASE_INSENSITIVE_STRATEGY
|
||||
|
||||
inherit
|
||||
CHARACTER_STRATEGY
|
||||
|
||||
feature
|
||||
|
||||
text_to_number (in: NATURAL_8): NATURAL_8
|
||||
do
|
||||
inspect
|
||||
in
|
||||
when 0x30 then
|
||||
Result := 0x0
|
||||
when 0x31 then
|
||||
Result := 1
|
||||
when 0x32 then
|
||||
Result := 2
|
||||
when 0x33 then
|
||||
Result := 3
|
||||
when 0x34 then
|
||||
Result := 4
|
||||
when 0x35 then
|
||||
Result := 5
|
||||
when 0x36 then
|
||||
Result := 6
|
||||
when 0x37 then
|
||||
Result := 7
|
||||
when 0x38 then
|
||||
Result := 8
|
||||
when 0x39 then
|
||||
Result := 9
|
||||
when 0x41 then
|
||||
Result := 10
|
||||
when 0x42 then
|
||||
Result := 11
|
||||
when 0x43 then
|
||||
Result := 12
|
||||
when 0x44 then
|
||||
Result := 13
|
||||
when 0x45 then
|
||||
Result := 14
|
||||
when 0x46 then
|
||||
Result := 15
|
||||
when 0x47 then
|
||||
Result := 16
|
||||
when 0x48 then
|
||||
Result := 17
|
||||
when 0x49 then
|
||||
Result := 18
|
||||
when 0x4a then
|
||||
Result := 19
|
||||
when 0x4b then
|
||||
Result := 20
|
||||
when 0x4c then
|
||||
Result := 21
|
||||
when 0x4d then
|
||||
Result := 22
|
||||
when 0x4e then
|
||||
Result := 23
|
||||
when 0x4f then
|
||||
Result := 24
|
||||
when 0x50 then
|
||||
Result := 25
|
||||
when 0x51 then
|
||||
Result := 26
|
||||
when 0x52 then
|
||||
Result := 27
|
||||
when 0x53 then
|
||||
Result := 28
|
||||
when 0x54 then
|
||||
Result := 29
|
||||
when 0x55 then
|
||||
Result := 30
|
||||
when 0x56 then
|
||||
Result := 31
|
||||
when 0x57 then
|
||||
Result := 32
|
||||
when 0x58 then
|
||||
Result := 33
|
||||
when 0x59 then
|
||||
Result := 34
|
||||
when 0x5a then
|
||||
Result := 35
|
||||
when 0x61 then
|
||||
Result := 10
|
||||
when 0x62 then
|
||||
Result := 11
|
||||
when 0x63 then
|
||||
Result := 12
|
||||
when 0x64 then
|
||||
Result := 13
|
||||
when 0x65 then
|
||||
Result := 14
|
||||
when 0x66 then
|
||||
Result := 15
|
||||
when 0x67 then
|
||||
Result := 16
|
||||
when 0x68 then
|
||||
Result := 17
|
||||
when 0x69 then
|
||||
Result := 18
|
||||
when 0x6a then
|
||||
Result := 19
|
||||
when 0x6b then
|
||||
Result := 20
|
||||
when 0x6c then
|
||||
Result := 21
|
||||
when 0x6d then
|
||||
Result := 22
|
||||
when 0x6e then
|
||||
Result := 23
|
||||
when 0x6f then
|
||||
Result := 24
|
||||
when 0x70 then
|
||||
Result := 25
|
||||
when 0x71 then
|
||||
Result := 26
|
||||
when 0x72 then
|
||||
Result := 27
|
||||
when 0x73 then
|
||||
Result := 28
|
||||
when 0x74 then
|
||||
Result := 29
|
||||
when 0x75 then
|
||||
Result := 30
|
||||
when 0x76 then
|
||||
Result := 31
|
||||
when 0x77 then
|
||||
Result := 32
|
||||
when 0x78 then
|
||||
Result := 33
|
||||
when 0x79 then
|
||||
Result := 34
|
||||
when 0x7a then
|
||||
Result := 35
|
||||
end
|
||||
end
|
||||
|
||||
number_to_text (in: NATURAL_8): NATURAL_8
|
||||
do
|
||||
inspect in
|
||||
when 0 then
|
||||
Result := 0x30
|
||||
when 1 then
|
||||
Result := 0x31
|
||||
when 2 then
|
||||
Result := 0x32
|
||||
when 3 then
|
||||
Result := 0x33
|
||||
when 4 then
|
||||
Result := 0x34
|
||||
when 5 then
|
||||
Result := 0x35
|
||||
when 6 then
|
||||
Result := 0x36
|
||||
when 7 then
|
||||
Result := 0x37
|
||||
when 8 then
|
||||
Result := 0x38
|
||||
when 9 then
|
||||
Result := 0x39
|
||||
when 10 then
|
||||
Result := 0x61
|
||||
when 11 then
|
||||
Result := 0x62
|
||||
when 12 then
|
||||
Result := 0x63
|
||||
when 13 then
|
||||
Result := 0x64
|
||||
when 14 then
|
||||
Result := 0x65
|
||||
when 15 then
|
||||
Result := 0x66
|
||||
when 16 then
|
||||
Result := 0x67
|
||||
when 17 then
|
||||
Result := 0x68
|
||||
when 18 then
|
||||
Result := 0x69
|
||||
when 19 then
|
||||
Result := 0x6a
|
||||
when 20 then
|
||||
Result := 0x6b
|
||||
when 21 then
|
||||
Result := 0x6c
|
||||
when 22 then
|
||||
Result := 0x6d
|
||||
when 23 then
|
||||
Result := 0x6e
|
||||
when 24 then
|
||||
Result := 0x6f
|
||||
when 25 then
|
||||
Result := 0x70
|
||||
when 26 then
|
||||
Result := 0x71
|
||||
when 27 then
|
||||
Result := 0x72
|
||||
when 28 then
|
||||
Result := 0x73
|
||||
when 29 then
|
||||
Result := 0x74
|
||||
when 30 then
|
||||
Result := 0x75
|
||||
when 31 then
|
||||
Result := 0x76
|
||||
when 32 then
|
||||
Result := 0x77
|
||||
when 33 then
|
||||
Result := 0x78
|
||||
when 34 then
|
||||
Result := 0x79
|
||||
when 35 then
|
||||
Result := 0x7a
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,276 @@
|
||||
note
|
||||
description: "Convert between character codes and numbers case-sensitive"
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "I believe the State exists for the development of individual lives, not individuals for the development of the state. - Julian Huxley (1878-1975)"
|
||||
|
||||
class
|
||||
CASE_SENSITIVE_STRATEGY
|
||||
|
||||
inherit
|
||||
CHARACTER_STRATEGY
|
||||
|
||||
feature
|
||||
|
||||
text_to_number (in: NATURAL_8): NATURAL_8
|
||||
do
|
||||
inspect
|
||||
in
|
||||
when 0x30 then
|
||||
Result := 0x0
|
||||
when 0x31 then
|
||||
Result := 1
|
||||
when 0x32 then
|
||||
Result := 2
|
||||
when 0x33 then
|
||||
Result := 3
|
||||
when 0x34 then
|
||||
Result := 4
|
||||
when 0x35 then
|
||||
Result := 5
|
||||
when 0x36 then
|
||||
Result := 6
|
||||
when 0x37 then
|
||||
Result := 7
|
||||
when 0x38 then
|
||||
Result := 8
|
||||
when 0x39 then
|
||||
Result := 9
|
||||
when 0x41 then
|
||||
Result := 10
|
||||
when 0x42 then
|
||||
Result := 11
|
||||
when 0x43 then
|
||||
Result := 12
|
||||
when 0x44 then
|
||||
Result := 13
|
||||
when 0x45 then
|
||||
Result := 14
|
||||
when 0x46 then
|
||||
Result := 15
|
||||
when 0x47 then
|
||||
Result := 16
|
||||
when 0x48 then
|
||||
Result := 17
|
||||
when 0x49 then
|
||||
Result := 18
|
||||
when 0x4a then
|
||||
Result := 19
|
||||
when 0x4b then
|
||||
Result := 20
|
||||
when 0x4c then
|
||||
Result := 21
|
||||
when 0x4d then
|
||||
Result := 22
|
||||
when 0x4e then
|
||||
Result := 23
|
||||
when 0x4f then
|
||||
Result := 24
|
||||
when 0x50 then
|
||||
Result := 25
|
||||
when 0x51 then
|
||||
Result := 26
|
||||
when 0x52 then
|
||||
Result := 27
|
||||
when 0x53 then
|
||||
Result := 28
|
||||
when 0x54 then
|
||||
Result := 29
|
||||
when 0x55 then
|
||||
Result := 30
|
||||
when 0x56 then
|
||||
Result := 31
|
||||
when 0x57 then
|
||||
Result := 32
|
||||
when 0x58 then
|
||||
Result := 33
|
||||
when 0x59 then
|
||||
Result := 34
|
||||
when 0x5a then
|
||||
Result := 35
|
||||
when 0x61 then
|
||||
Result := 36
|
||||
when 0x62 then
|
||||
Result := 37
|
||||
when 0x63 then
|
||||
Result := 38
|
||||
when 0x64 then
|
||||
Result := 39
|
||||
when 0x65 then
|
||||
Result := 40
|
||||
when 0x66 then
|
||||
Result := 41
|
||||
when 0x67 then
|
||||
Result := 42
|
||||
when 0x68 then
|
||||
Result := 43
|
||||
when 0x69 then
|
||||
Result := 44
|
||||
when 0x6a then
|
||||
Result := 45
|
||||
when 0x6b then
|
||||
Result := 46
|
||||
when 0x6c then
|
||||
Result := 47
|
||||
when 0x6d then
|
||||
Result := 48
|
||||
when 0x6e then
|
||||
Result := 49
|
||||
when 0x6f then
|
||||
Result := 50
|
||||
when 0x70 then
|
||||
Result := 51
|
||||
when 0x71 then
|
||||
Result := 52
|
||||
when 0x72 then
|
||||
Result := 53
|
||||
when 0x73 then
|
||||
Result := 54
|
||||
when 0x74 then
|
||||
Result := 55
|
||||
when 0x75 then
|
||||
Result := 56
|
||||
when 0x76 then
|
||||
Result := 57
|
||||
when 0x77 then
|
||||
Result := 58
|
||||
when 0x78 then
|
||||
Result := 59
|
||||
when 0x79 then
|
||||
Result := 60
|
||||
when 0x7a then
|
||||
Result := 61
|
||||
end
|
||||
end
|
||||
|
||||
number_to_text (in: NATURAL_8): NATURAL_8
|
||||
do
|
||||
inspect in
|
||||
when 0 then
|
||||
Result := 0x30
|
||||
when 1 then
|
||||
Result := 0x31
|
||||
when 2 then
|
||||
Result := 0x32
|
||||
when 3 then
|
||||
Result := 0x33
|
||||
when 4 then
|
||||
Result := 0x34
|
||||
when 5 then
|
||||
Result := 0x35
|
||||
when 6 then
|
||||
Result := 0x36
|
||||
when 7 then
|
||||
Result := 0x37
|
||||
when 8 then
|
||||
Result := 0x38
|
||||
when 9 then
|
||||
Result := 0x39
|
||||
when 10 then
|
||||
Result := 0x41
|
||||
when 11 then
|
||||
Result := 0x42
|
||||
when 12 then
|
||||
Result := 0x43
|
||||
when 13 then
|
||||
Result := 0x44
|
||||
when 14 then
|
||||
Result := 0x45
|
||||
when 15 then
|
||||
Result := 0x46
|
||||
when 16 then
|
||||
Result := 0x47
|
||||
when 17 then
|
||||
Result := 0x48
|
||||
when 18 then
|
||||
Result := 0x49
|
||||
when 19 then
|
||||
Result := 0x4a
|
||||
when 20 then
|
||||
Result := 0x4b
|
||||
when 21 then
|
||||
Result := 0x4c
|
||||
when 22 then
|
||||
Result := 0x4d
|
||||
when 23 then
|
||||
Result := 0x4e
|
||||
when 24 then
|
||||
Result := 0x4f
|
||||
when 25 then
|
||||
Result := 0x50
|
||||
when 26 then
|
||||
Result := 0x51
|
||||
when 27 then
|
||||
Result := 0x52
|
||||
when 28 then
|
||||
Result := 0x53
|
||||
when 29 then
|
||||
Result := 0x54
|
||||
when 30 then
|
||||
Result := 0x55
|
||||
when 31 then
|
||||
Result := 0x56
|
||||
when 32 then
|
||||
Result := 0x57
|
||||
when 33 then
|
||||
Result := 0x58
|
||||
when 34 then
|
||||
Result := 0x59
|
||||
when 35 then
|
||||
Result := 0x5a
|
||||
when 36 then
|
||||
Result := 0x61
|
||||
when 37 then
|
||||
Result := 0x62
|
||||
when 38 then
|
||||
Result := 0x63
|
||||
when 39 then
|
||||
Result := 0x64
|
||||
when 40 then
|
||||
Result := 0x65
|
||||
when 41 then
|
||||
Result := 0x66
|
||||
when 42 then
|
||||
Result := 0x67
|
||||
when 43 then
|
||||
Result := 0x68
|
||||
when 44 then
|
||||
Result := 0x69
|
||||
when 45 then
|
||||
Result := 0x6a
|
||||
when 46 then
|
||||
Result := 0x6b
|
||||
when 47 then
|
||||
Result := 0x6c
|
||||
when 48 then
|
||||
Result := 0x6d
|
||||
when 49 then
|
||||
Result := 0x6e
|
||||
when 50 then
|
||||
Result := 0x6f
|
||||
when 51 then
|
||||
Result := 0x70
|
||||
when 52 then
|
||||
Result := 0x71
|
||||
when 53 then
|
||||
Result := 0x72
|
||||
when 54 then
|
||||
Result := 0x73
|
||||
when 55 then
|
||||
Result := 0x74
|
||||
when 56 then
|
||||
Result := 0x75
|
||||
when 57 then
|
||||
Result := 0x76
|
||||
when 58 then
|
||||
Result := 0x77
|
||||
when 59 then
|
||||
Result := 0x78
|
||||
when 60 then
|
||||
Result := 0x79
|
||||
when 61 then
|
||||
Result := 0x7a
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
note
|
||||
description: "A strategy for converting character codes to numbers and vica-versa"
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Free speech is meaningless unless it tolerates the speech that we hate. - Henry J. Hyde, U.S. Congressman, Speech, 5/3/91"
|
||||
|
||||
deferred class
|
||||
CHARACTER_STRATEGY
|
||||
|
||||
feature
|
||||
|
||||
text_to_number (in: NATURAL_8): NATURAL_8
|
||||
deferred
|
||||
end
|
||||
|
||||
number_to_text (in: NATURAL_8): NATURAL_8
|
||||
deferred
|
||||
end
|
||||
end
|
||||
77
contrib/ise_library/math/eapml/facilities/integer_x_access.e
Normal file
77
contrib/ise_library/math/eapml/facilities/integer_x_access.e
Normal file
@@ -0,0 +1,77 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_ACCESS}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "It is error alone which needs the support of government. Truth can stand by itself. - Thomas Jefferson (1743-1846), U.S. President, Notes on the State of Virginia, 1782"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_ACCESS
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_SIZING
|
||||
SPECIAL_ACCESS
|
||||
rename
|
||||
get_str as get_str_special
|
||||
end
|
||||
|
||||
feature
|
||||
|
||||
get_string (op: READABLE_INTEGER_X; base: INTEGER): STRING_8
|
||||
require
|
||||
base >= 2
|
||||
base <= 62
|
||||
local
|
||||
xp: SPECIAL [NATURAL_32]
|
||||
xp_offset: INTEGER
|
||||
x_size: INTEGER
|
||||
str: STRING_8
|
||||
str_offset: INTEGER
|
||||
return_str: STRING_8
|
||||
return_str_offset: INTEGER
|
||||
str_size: INTEGER
|
||||
alloc_size: INTEGER
|
||||
num_to_text: CHARACTER_STRATEGY
|
||||
i: INTEGER
|
||||
do
|
||||
x_size := op.count
|
||||
if base <= 35 then
|
||||
create {CASE_INSENSITIVE_STRATEGY}num_to_text
|
||||
else
|
||||
create {CASE_SENSITIVE_STRATEGY}num_to_text
|
||||
end
|
||||
alloc_size := sizeinbase (op.item, 0, x_size.abs, base)
|
||||
alloc_size := alloc_size + (x_size < 0).to_integer
|
||||
create Result.make_filled ('%U', alloc_size)
|
||||
return_str := Result
|
||||
return_str_offset := 1
|
||||
if x_size < 0 then
|
||||
return_str [return_str_offset] := '-'
|
||||
return_str_offset := return_str_offset + 1
|
||||
x_size := -x_size
|
||||
end
|
||||
xp := op.item
|
||||
xp_offset := 0
|
||||
if not pow2_p (base.to_natural_32) then
|
||||
create xp.make_filled (0, x_size + 1)
|
||||
xp.copy_data (op.item, 0, 0, x_size)
|
||||
end
|
||||
str_size := get_str_special (return_str, return_str_offset, base, xp, xp_offset, x_size)
|
||||
str := return_str
|
||||
str.remove_tail (alloc_size - str_size - (return_str_offset - 1))
|
||||
str_offset := return_str_offset
|
||||
if str [str_offset] = (0x0).to_character_8 and str_size /= 1 then
|
||||
str_size := str_size - 1
|
||||
str_offset := str_offset + 1
|
||||
end
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= str_size
|
||||
loop
|
||||
return_str [return_str_offset + i] := num_to_text.number_to_text (str [str_offset + i].code.to_natural_8).to_character_8
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
914
contrib/ise_library/math/eapml/facilities/integer_x_arithmetic.e
Normal file
914
contrib/ise_library/math/eapml/facilities/integer_x_arithmetic.e
Normal file
@@ -0,0 +1,914 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_ARITHMETIC}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Every man should know that his conversations, his correspondence, and his personal life are private. - Lyndon B. Johnson (1908-1973), Remarks, 3/10/67"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_ARITHMETIC
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_ARITHMETIC
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
SPECIAL_COMPARISON
|
||||
SPECIAL_UTILITY
|
||||
|
||||
feature
|
||||
|
||||
add (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X)
|
||||
-- Set `rop' to `op1' + `op2'.
|
||||
local
|
||||
wp: SPECIAL [NATURAL_32]
|
||||
wp_offset: INTEGER
|
||||
up: SPECIAL [NATURAL_32]
|
||||
vp: SPECIAL [NATURAL_32]
|
||||
usize: INTEGER_32
|
||||
vsize: INTEGER_32
|
||||
wsize: INTEGER_32
|
||||
abs_usize: INTEGER_32
|
||||
abs_vsize: INTEGER_32
|
||||
pointer_temp: READABLE_INTEGER_X
|
||||
int_temp: INTEGER_32
|
||||
junk2: NATURAL_32
|
||||
cy_limb: NATURAL_32
|
||||
op1: READABLE_INTEGER_X
|
||||
op2: READABLE_INTEGER_X
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
op1 := op1_a
|
||||
op2 := op2_a
|
||||
usize := op1.count
|
||||
vsize := op2.count
|
||||
abs_usize := usize.abs
|
||||
abs_vsize := vsize.abs
|
||||
if abs_usize < abs_vsize then
|
||||
pointer_temp := op1
|
||||
op1 := op2
|
||||
op2 := pointer_temp
|
||||
int_temp := usize
|
||||
usize := vsize
|
||||
vsize := int_temp
|
||||
int_temp := abs_usize
|
||||
abs_usize := abs_vsize
|
||||
abs_vsize := int_temp
|
||||
end
|
||||
wsize := abs_usize + 1
|
||||
target.resize (wsize)
|
||||
up := op1.item
|
||||
vp := op2.item
|
||||
wp := target.item
|
||||
if usize.bit_xor (vsize) < 0 then
|
||||
if abs_usize /= abs_vsize then
|
||||
sub_special (wp, 0, up, 0, abs_usize, vp, 0, abs_vsize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := abs_usize
|
||||
wsize := normalize (wp, wp_offset, wsize)
|
||||
if usize < 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
elseif cmp (up, 0, vp, 0, abs_usize) < 0 then
|
||||
sub_n (wp, 0, vp, 0, up, 0, abs_usize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := abs_usize
|
||||
wsize := normalize (wp, wp_offset, wsize)
|
||||
if usize >= 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
else
|
||||
sub_n (wp, 0, up, 0, vp, 0, abs_usize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := abs_usize
|
||||
wsize := normalize (wp, wp_offset, wsize)
|
||||
if usize < 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
end
|
||||
else
|
||||
add_special (wp, 0, up, 0, abs_usize, vp, 0, abs_vsize, carry)
|
||||
cy_limb := carry.item
|
||||
wp [wp_offset + abs_usize] := cy_limb
|
||||
wsize := abs_usize + cy_limb.to_integer_32
|
||||
if usize < 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
end
|
||||
target.count := wsize
|
||||
end
|
||||
|
||||
add_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
|
||||
-- Set `rop' to `op1' + `op2'.
|
||||
local
|
||||
usize: INTEGER_32
|
||||
wsize: INTEGER_32
|
||||
abs_usize: INTEGER_32
|
||||
cy: NATURAL_32
|
||||
junk2: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
usize := op1.count
|
||||
abs_usize := usize.abs
|
||||
wsize := abs_usize + 1
|
||||
target.resize (wsize)
|
||||
if abs_usize = 0 then
|
||||
target.item [0] := op2
|
||||
if op2 /= 0 then
|
||||
target.count := 1
|
||||
else
|
||||
target.count := 0
|
||||
end
|
||||
else
|
||||
if usize >= 0 then
|
||||
add_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
|
||||
cy := carry.item
|
||||
target.item [abs_usize] := cy
|
||||
wsize := abs_usize + cy.to_integer_32
|
||||
else
|
||||
if abs_usize = 1 and op1.item [0] < op2 then
|
||||
target.item [0] := op2 - op1.item [0]
|
||||
wsize := 1
|
||||
else
|
||||
sub_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
|
||||
junk2 := carry.item
|
||||
if target.item [abs_usize - 1] = 0 then
|
||||
wsize := - (abs_usize - 1)
|
||||
else
|
||||
wsize := - (abs_usize)
|
||||
end
|
||||
end
|
||||
end
|
||||
target.count := wsize
|
||||
end
|
||||
end
|
||||
|
||||
aorsmul (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X; sub_a: INTEGER_32)
|
||||
local
|
||||
xsize: INTEGER_32
|
||||
ysize: INTEGER_32
|
||||
tsize: INTEGER_32
|
||||
wsize: INTEGER_32
|
||||
wsize_signed: INTEGER_32
|
||||
wp: INTEGER_32
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
c: NATURAL_32
|
||||
high: NATURAL_32
|
||||
tmp_marker: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER_32
|
||||
current_temp: READABLE_INTEGER_X
|
||||
int_temp: INTEGER_32
|
||||
usize: INTEGER_32
|
||||
sub_l: INTEGER_32
|
||||
junk2: NATURAL_32
|
||||
op1: READABLE_INTEGER_X
|
||||
op2: READABLE_INTEGER_X
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
op1 := op1_a
|
||||
op2 := op2_a
|
||||
sub_l := sub_a
|
||||
xsize := op1.count
|
||||
ysize := op2.count
|
||||
if xsize = 0 or ysize = 0 then
|
||||
else
|
||||
if ysize.abs > xsize.abs then
|
||||
current_temp := op1
|
||||
op1 := op2
|
||||
op2 := current_temp
|
||||
int_temp := xsize
|
||||
xsize := ysize
|
||||
ysize := int_temp
|
||||
end
|
||||
sub_l := sub_l.bit_xor (ysize)
|
||||
ysize := ysize.abs
|
||||
if ysize = 1 then
|
||||
aorsmul_1 (target, op1, op2.item [0], sub_l)
|
||||
else
|
||||
sub_l := sub_l.bit_xor (xsize)
|
||||
xsize := xsize.abs
|
||||
wsize_signed := target.count
|
||||
sub_l := sub_l.bit_xor (wsize_signed)
|
||||
wsize := wsize_signed.abs
|
||||
tsize := xsize + ysize
|
||||
if wsize > tsize then
|
||||
if wsize + 1 > target.capacity then
|
||||
target.resize (wsize)
|
||||
end
|
||||
else
|
||||
if tsize + 1 > target.capacity then
|
||||
target.resize (tsize)
|
||||
end
|
||||
end
|
||||
if wsize_signed = 0 then
|
||||
mul_special (target.item, 0, op1.item, 0, xsize, op2.item, 0, ysize, carry)
|
||||
high := carry.item
|
||||
if high = 0 then
|
||||
tsize := tsize - 1
|
||||
end
|
||||
if sub_l >= 0 then
|
||||
target.count := tsize
|
||||
else
|
||||
target.count := -tsize
|
||||
end
|
||||
else
|
||||
create tmp_marker.make_filled (0, tsize)
|
||||
tp := tmp_marker
|
||||
tp_offset := 0
|
||||
mul_special (tmp_marker, 0, op1.item, 0, xsize, op2.item, 0, ysize, carry)
|
||||
high := carry.item
|
||||
if high = 0 then
|
||||
tsize := tsize - 1
|
||||
end
|
||||
if sub_l >= 0 then
|
||||
usize := wsize
|
||||
if usize < tsize then
|
||||
usize := tsize
|
||||
tp_offset := wp
|
||||
tsize := wsize
|
||||
wsize := usize
|
||||
end
|
||||
add_special (target.item, wp, op1.item, 0, usize, tp, 0, tsize, carry)
|
||||
c := carry.item
|
||||
target.item [wp + wsize] := c
|
||||
if c /= 0 then
|
||||
wsize := wsize + 1
|
||||
end
|
||||
else
|
||||
usize := wsize
|
||||
if usize < tsize or usize = tsize and cmp (target.item, wp, tmp_marker, 0, usize) < 0 then
|
||||
usize := tsize
|
||||
tp_offset := wp
|
||||
tsize := wsize
|
||||
wsize := usize
|
||||
wsize_signed := -wsize_signed
|
||||
end
|
||||
sub_special (target.item, wp, target.item, wp, usize, tp, tp_offset, tsize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := usize
|
||||
from
|
||||
until
|
||||
wsize > 0 or target.item [wp + wsize - 1] /= 0
|
||||
loop
|
||||
wsize := wsize - 1
|
||||
end
|
||||
end
|
||||
if wsize_signed >= 0 then
|
||||
target.count := wsize
|
||||
else
|
||||
target.count := -wsize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
aorsmul_1 (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL_32; sub_a: INTEGER_32)
|
||||
local
|
||||
xsize: INTEGER_32
|
||||
wsize: INTEGER_32
|
||||
wsize_signed: INTEGER_32
|
||||
new_wsize: INTEGER_32
|
||||
min_size: INTEGER_32
|
||||
dsize: INTEGER_32
|
||||
xp: INTEGER_32
|
||||
wp: INTEGER_32
|
||||
cy: NATURAL_32
|
||||
sub_l: INTEGER_32
|
||||
cy2: NATURAL_32
|
||||
d: INTEGER_32
|
||||
s: INTEGER_32
|
||||
n: INTEGER_32
|
||||
x: NATURAL_32
|
||||
p: INTEGER_32
|
||||
cy__: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
sub_l := sub_a
|
||||
xsize := op1.count
|
||||
if xsize = 0 or op2 = 0 then
|
||||
else
|
||||
sub_l := sub_l.bit_xor (xsize)
|
||||
xsize := xsize.abs
|
||||
wsize_signed := target.count
|
||||
if wsize_signed = 0 then
|
||||
target.resize (xsize + 1)
|
||||
wp := 0
|
||||
mul_1 (target.item, 0, op1.item, 0, xsize, op2, carry)
|
||||
cy := carry.item
|
||||
target.item [xsize] := cy
|
||||
if cy /= 0 then
|
||||
xsize := xsize + 1
|
||||
end
|
||||
if sub_l >= 0 then
|
||||
target.count := xsize
|
||||
else
|
||||
target.count := -xsize
|
||||
end
|
||||
else
|
||||
sub_l := sub_l.bit_xor (wsize_signed)
|
||||
wsize := wsize_signed.abs
|
||||
new_wsize := wsize.max (xsize)
|
||||
target.resize (new_wsize + 1)
|
||||
wp := 0
|
||||
xp := 0
|
||||
min_size := wsize.min (xsize)
|
||||
if sub_l >= 0 then
|
||||
addmul_1 (target.item, 0, op1.item, 0, min_size, op2, carry)
|
||||
cy := carry.item
|
||||
wp := wp + min_size
|
||||
xp := xp + min_size
|
||||
dsize := xsize - wsize
|
||||
if dsize /= 0 then
|
||||
if dsize > 0 then
|
||||
mul_1 (target.item, wp, op1.item, xp, min_size, op2, carry)
|
||||
cy2 := carry.item
|
||||
else
|
||||
dsize := -dsize
|
||||
cy2 := 0
|
||||
end
|
||||
add_1 (target.item, wp, target.item, wp, dsize, cy, carry)
|
||||
cy := cy2 + carry.item
|
||||
end
|
||||
target.item [wp + dsize] := cy
|
||||
if cy /= 0 then
|
||||
new_wsize := new_wsize + 1
|
||||
end
|
||||
else
|
||||
submul_1 (target.item, wp, op1.item, xp, min_size, op2, carry)
|
||||
cy := carry.item
|
||||
if wsize >= xsize then
|
||||
if wsize /= xsize then
|
||||
sub_1 (target.item, wp + xsize, op1.item, wp + xsize, wsize - xsize, cy, carry)
|
||||
cy := carry.item
|
||||
if cy /= 0 then
|
||||
target.item [wp + new_wsize] := (-cy.to_integer_32).bit_not.to_natural_32
|
||||
d := wp
|
||||
s := wp
|
||||
n := new_wsize
|
||||
from
|
||||
target.item [d] := target.item [s].bit_not
|
||||
d := d + 1
|
||||
s := s + 1
|
||||
n := n - 1
|
||||
until
|
||||
n = 0
|
||||
loop
|
||||
target.item [d] := target.item [s].bit_not
|
||||
d := d + 1
|
||||
s := s + 1
|
||||
n := n - 1
|
||||
end
|
||||
new_wsize := new_wsize + 1
|
||||
p := wp
|
||||
x := target.item [p] + 1
|
||||
target.item [p] := x
|
||||
if x < 1 then
|
||||
from
|
||||
p := p + 1
|
||||
target.item [p] := target.item [p] + 1
|
||||
until
|
||||
target.item [p] /= 0
|
||||
loop
|
||||
p := p + 1
|
||||
target.item [p] := target.item [p] + 1
|
||||
end
|
||||
end
|
||||
wsize_signed := -wsize_signed
|
||||
end
|
||||
else
|
||||
d := wp
|
||||
s := wp
|
||||
n := wsize
|
||||
from
|
||||
target.item [d] := target.item [s].bit_not
|
||||
s := s + 1
|
||||
d := d + 1
|
||||
n := n - 1
|
||||
until
|
||||
n = 0
|
||||
loop
|
||||
target.item [d] := target.item [s].bit_not
|
||||
s := s + 1
|
||||
d := d + 1
|
||||
n := n - 1
|
||||
end
|
||||
add_1 (target.item, wp, target.item, wp, wsize, 1, carry)
|
||||
cy := carry.item
|
||||
cy := cy - 1
|
||||
if cy = (0).to_natural_32.bit_not then
|
||||
cy2 := cy2 + 1
|
||||
end
|
||||
cy := cy + cy2
|
||||
mul_1 (target.item, wp + wsize, target.item, xp + wsize, xsize - wsize, op2, carry)
|
||||
cy__ := carry.item
|
||||
add_1 (target.item, wp + wsize, target.item, wp + wsize, xsize - wsize, cy, carry)
|
||||
cy := cy__ + carry.item
|
||||
target.item [wp + new_wsize] := cy
|
||||
if cy /= 0 then
|
||||
new_wsize := new_wsize + 1
|
||||
end
|
||||
if cy2 /= 0 then
|
||||
p := wp + wsize
|
||||
x := target.item [p]
|
||||
target.item [p] := x - 1
|
||||
if x < 1 then
|
||||
from
|
||||
p := p + 1
|
||||
target.item [p] := target.item [p] - 1
|
||||
until
|
||||
target.item [p] = 0
|
||||
loop
|
||||
p := p + 1
|
||||
target.item [p] := target.item [p] - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
wsize_signed := -wsize_signed
|
||||
end
|
||||
end
|
||||
from
|
||||
until
|
||||
new_wsize <= 0 or target.item [(wp + new_wsize) * 4] /= 0
|
||||
loop
|
||||
new_wsize := new_wsize - 1
|
||||
end
|
||||
end
|
||||
if wsize_signed >= 0 then
|
||||
target.count := new_wsize
|
||||
else
|
||||
target.count := -new_wsize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sub (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X)
|
||||
-- Set `rop' to `op1' - `op2'.
|
||||
local
|
||||
usize: INTEGER_32
|
||||
vsize: INTEGER_32
|
||||
wsize: INTEGER_32
|
||||
abs_usize: INTEGER_32
|
||||
abs_vsize: INTEGER_32
|
||||
pointer_temp: READABLE_INTEGER_X
|
||||
integer_temp: INTEGER_32
|
||||
junk2: NATURAL_32
|
||||
cy_limb: NATURAL_32
|
||||
op1: READABLE_INTEGER_X
|
||||
op2: READABLE_INTEGER_X
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
op1 := op1_a
|
||||
op2 := op2_a
|
||||
usize := op1.count
|
||||
vsize := -op2.count
|
||||
abs_usize := usize.abs
|
||||
abs_vsize := vsize.abs
|
||||
if abs_usize < abs_vsize then
|
||||
pointer_temp := op1
|
||||
op1 := op2
|
||||
op2 := pointer_temp
|
||||
integer_temp := usize
|
||||
usize := vsize
|
||||
vsize := integer_temp
|
||||
integer_temp := abs_usize
|
||||
abs_usize := abs_vsize
|
||||
abs_vsize := integer_temp
|
||||
end
|
||||
wsize := abs_usize + 1
|
||||
target.resize (wsize)
|
||||
if usize.bit_xor (vsize) < 0 then
|
||||
if abs_usize /= abs_vsize then
|
||||
sub_special (target.item, 0, op1.item, 0, abs_usize, op2.item, 0, abs_vsize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := abs_usize
|
||||
from
|
||||
until
|
||||
wsize <= 0 or target.item [wsize - 1] /= 0
|
||||
loop
|
||||
wsize := wsize - 1
|
||||
end
|
||||
if usize < 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
elseif cmp (op1.item, 0, op2.item, 0, abs_usize) < 0 then
|
||||
sub_n (target.item, 0, op2.item, 0, op1.item, 0, abs_usize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := abs_usize
|
||||
from
|
||||
until
|
||||
wsize <= 0 or target.item [wsize - 1] /= 0
|
||||
loop
|
||||
wsize := wsize - 1
|
||||
end
|
||||
if usize >= 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
else
|
||||
sub_n (target.item, 0, op1.item, 0, op2.item, 0, abs_usize, carry)
|
||||
junk2 := carry.item
|
||||
wsize := abs_usize
|
||||
from
|
||||
until
|
||||
wsize <= 0 or target.item [wsize - 1] /= 0
|
||||
loop
|
||||
wsize := wsize - 1
|
||||
end
|
||||
if usize < 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
end
|
||||
else
|
||||
add_special (target.item, 0, op1.item, 0, abs_usize, op2.item, 0, abs_vsize, carry)
|
||||
cy_limb := carry.item
|
||||
target.item [abs_usize] := cy_limb
|
||||
wsize := abs_usize + cy_limb.to_integer_32
|
||||
if usize < 0 then
|
||||
wsize := -wsize
|
||||
end
|
||||
end
|
||||
target.count := wsize
|
||||
end
|
||||
|
||||
sub_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
|
||||
-- Set `rop' to `op1' - `op2'.
|
||||
local
|
||||
usize: INTEGER_32
|
||||
wsize: INTEGER_32
|
||||
abs_usize: INTEGER_32
|
||||
vval: NATURAL_32
|
||||
cy: NATURAL_32
|
||||
junk2: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
usize := op1.count
|
||||
abs_usize := usize.abs
|
||||
wsize := abs_usize + 1
|
||||
target.resize (wsize)
|
||||
if abs_usize = 0 then
|
||||
target.item [0] := vval
|
||||
if op2 /= 0 then
|
||||
target.count := -1
|
||||
else
|
||||
target.count := 0
|
||||
end
|
||||
else
|
||||
if usize < 0 then
|
||||
add_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
|
||||
cy := carry.item
|
||||
target.item [abs_usize] := cy
|
||||
wsize := - (abs_usize + cy.to_integer_32)
|
||||
else
|
||||
if abs_usize = 1 and op1.item [0] < op2 then
|
||||
target.item [0] := op2 - op1.item [0]
|
||||
wsize := -1
|
||||
else
|
||||
sub_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
|
||||
junk2 := carry.item
|
||||
if target.item [abs_usize - 1] = 0 then
|
||||
wsize := abs_usize - 1
|
||||
else
|
||||
wsize := abs_usize
|
||||
end
|
||||
end
|
||||
end
|
||||
target.count := wsize
|
||||
end
|
||||
end
|
||||
|
||||
ui_sub (target: READABLE_INTEGER_X; op1: NATURAL_32; op2: READABLE_INTEGER_X)
|
||||
-- Set `rop' to `op1' - `op2'.
|
||||
local
|
||||
vn: INTEGER_32
|
||||
wn: INTEGER_32
|
||||
cy: NATURAL_32
|
||||
junk2: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
vn := op2.count
|
||||
if vn > 1 then
|
||||
if vn > target.capacity then
|
||||
target.resize (vn)
|
||||
end
|
||||
sub_1 (target.item, 0, op2.item, 0, vn, op1, carry)
|
||||
junk2 := carry.item
|
||||
if target.item [vn - 1] = 0 then
|
||||
wn := - (vn - 1)
|
||||
else
|
||||
wn := - vn
|
||||
end
|
||||
elseif vn = 1 then
|
||||
if op1 >= op2.item [0] then
|
||||
target.item [0] := op1 - op2.item [0]
|
||||
if target.item [0] /= 0 then
|
||||
wn := 1
|
||||
else
|
||||
wn := 0
|
||||
end
|
||||
else
|
||||
target.item [0] := op2.item [0] - op1
|
||||
wn := -1
|
||||
end
|
||||
elseif vn = 0 then
|
||||
target.item [0] := op1
|
||||
if op1 /= 0 then
|
||||
wn := 1
|
||||
else
|
||||
wn := 0
|
||||
end
|
||||
else
|
||||
vn := -vn
|
||||
target.resize (vn + 1)
|
||||
add_1 (target.item, 0, op2.item, 0, vn, op1, carry)
|
||||
cy := carry.item
|
||||
target.item [vn] := cy
|
||||
if cy /= 0 then
|
||||
wn := vn + 1
|
||||
else
|
||||
wn := vn
|
||||
end
|
||||
end
|
||||
target.count := wn
|
||||
end
|
||||
|
||||
addmul (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X)
|
||||
-- Set `rop' to `rop' + `op1' times `op2'.
|
||||
do
|
||||
aorsmul (target, op1, op2, 0)
|
||||
end
|
||||
|
||||
addmul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
|
||||
-- Set `rop' to `rop' + `op1' times `op2'.
|
||||
do
|
||||
aorsmul_1 (target, op1, op2, 0)
|
||||
end
|
||||
|
||||
submul (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X)
|
||||
-- Set `rop' to `rop' - `op1' times `op2'.
|
||||
do
|
||||
aorsmul (target, op1, op2, -1)
|
||||
end
|
||||
|
||||
submul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
|
||||
-- Set `rop' to `rop' - `op1' times `op2'.
|
||||
do
|
||||
aorsmul_1 (target, op1, op2, -1)
|
||||
end
|
||||
|
||||
mul (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X)
|
||||
-- Set `rop' to `op1' times `op2'.
|
||||
local
|
||||
usize: INTEGER
|
||||
vsize: INTEGER
|
||||
wsize: INTEGER
|
||||
sign_product: INTEGER
|
||||
vp: SPECIAL [NATURAL_32]
|
||||
vp_offset: INTEGER
|
||||
up: SPECIAL [NATURAL_32]
|
||||
up_offset: INTEGER
|
||||
wp: SPECIAL [NATURAL_32]
|
||||
wp_offset: INTEGER
|
||||
cy_limb: NATURAL_32
|
||||
op_temp: READABLE_INTEGER_X
|
||||
size_temp: INTEGER_32
|
||||
op1: READABLE_INTEGER_X
|
||||
op2: READABLE_INTEGER_X
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
op1 := op1_a
|
||||
op2 := op2_a
|
||||
usize := op1.count
|
||||
vsize := op2.count
|
||||
sign_product := usize.bit_xor (vsize)
|
||||
usize := usize.abs
|
||||
vsize := vsize.abs
|
||||
if usize = 0 or vsize = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
if vsize = 1 then
|
||||
if usize + 1 > target.capacity then
|
||||
target.resize (usize + 1)
|
||||
end
|
||||
wp := target.item
|
||||
mul_1 (target.item, 0, op1.item, 0, usize, op2.item [0], carry)
|
||||
cy_limb := carry.item
|
||||
target.item [usize] := cy_limb
|
||||
if cy_limb /= 0 then
|
||||
usize := usize + 1
|
||||
end
|
||||
if sign_product >= 0 then
|
||||
target.count := usize
|
||||
else
|
||||
target.count := -usize
|
||||
end
|
||||
else
|
||||
wsize := usize + vsize
|
||||
if wsize <= 32 and target /= op1 and target /= op2 then
|
||||
target.resize (wsize)
|
||||
wp := target.item
|
||||
if usize > vsize then
|
||||
mul_basecase (wp, 0, op1.item, 0, usize, op2.item, 0, vsize)
|
||||
else
|
||||
mul_basecase (wp, 0, op2.item, 0, vsize, op1.item, 0, usize)
|
||||
end
|
||||
wsize := wsize - (wp [wp_offset + wsize - 1] = 0).to_integer
|
||||
if sign_product >= 0 then
|
||||
target.count := wsize
|
||||
else
|
||||
target.count := -wsize
|
||||
end
|
||||
else
|
||||
if usize < vsize then
|
||||
op_temp := op1
|
||||
op1 := op2
|
||||
op2 := op_temp
|
||||
size_temp := usize
|
||||
usize := vsize
|
||||
vsize := size_temp
|
||||
end
|
||||
up := op1.item
|
||||
up_offset := 0
|
||||
vp := op2.item
|
||||
vp_offset := 0
|
||||
wp := target.item
|
||||
wp_offset := 0
|
||||
if target.capacity < wsize then
|
||||
create wp.make_filled (0, wsize)
|
||||
target.item := wp
|
||||
else
|
||||
if wp = up then
|
||||
create up.make_filled (0, usize)
|
||||
if wp = vp then
|
||||
vp := up
|
||||
end
|
||||
up.copy_data (wp, 0, 0, usize)
|
||||
elseif wp = vp then
|
||||
create vp.make_filled (0, vsize)
|
||||
vp.copy_data (wp, 0, 0, vsize)
|
||||
end
|
||||
end
|
||||
mul_special (wp, 0, up, 0, usize, vp, 0, vsize, carry)
|
||||
cy_limb := carry.item
|
||||
wsize := usize + vsize
|
||||
wsize := wsize - (cy_limb = 0).to_integer
|
||||
if sign_product < 0 then
|
||||
target.count := -wsize
|
||||
else
|
||||
target.count := wsize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mul_2exp (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; count_a: INTEGER)
|
||||
local
|
||||
usize: INTEGER
|
||||
abs_usize: INTEGER
|
||||
wsize: INTEGER
|
||||
limb_count: INTEGER
|
||||
wp: SPECIAL [NATURAL_32]
|
||||
wp_offset: INTEGER
|
||||
wlimb: NATURAL_32
|
||||
count: INTEGER
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
count := count_a
|
||||
usize := op1.count
|
||||
abs_usize := usize.abs
|
||||
if usize = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
limb_count := count // limb_bits
|
||||
wsize := abs_usize + limb_count + 1
|
||||
target.resize (wsize)
|
||||
wp := target.item
|
||||
wsize := abs_usize + limb_count
|
||||
count := count \\ limb_bits
|
||||
if count /= 0 then
|
||||
lshift (wp, wp_offset + limb_count, op1.item, 0, abs_usize, count, carry)
|
||||
wlimb := carry.item
|
||||
if wlimb /= 0 then
|
||||
wp [wp_offset + wsize] := wlimb
|
||||
wsize := wsize + 1
|
||||
end
|
||||
else
|
||||
wp.copy_data (op1.item, 0, wp_offset + limb_count, abs_usize)
|
||||
end
|
||||
wp.fill_with (0, wp_offset, wp_offset + limb_count - 1)
|
||||
if usize >= 0 then
|
||||
target.count := wsize
|
||||
else
|
||||
target.count := -wsize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mul_si (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: INTEGER)
|
||||
local
|
||||
size: INTEGER
|
||||
sign_product: INTEGER
|
||||
sml: NATURAL_32
|
||||
cy: NATURAL_32
|
||||
pp: SPECIAL [NATURAL_32]
|
||||
pp_offset: INTEGER
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
size := op1.count
|
||||
sign_product := size
|
||||
if size = 0 or op2 = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
size := size.abs
|
||||
sml := op2.abs.to_natural_32
|
||||
target.resize (size + 1)
|
||||
pp := target.item
|
||||
mul_1 (pp, pp_offset, op1.item, 0, size, sml, carry)
|
||||
cy := carry.item
|
||||
pp [pp_offset + size] := cy
|
||||
size := size + (cy /= 0).to_integer
|
||||
end
|
||||
if sign_product < 0 xor op2 < 0 then
|
||||
target.count := -size
|
||||
else
|
||||
target.count := size
|
||||
end
|
||||
end
|
||||
|
||||
mul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL_32)
|
||||
local
|
||||
size: INTEGER
|
||||
sign_product: INTEGER
|
||||
sml: NATURAL_32
|
||||
cy: NATURAL_32
|
||||
pp: SPECIAL [NATURAL_32]
|
||||
pp_offset: INTEGER
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
size := op1.count
|
||||
sign_product := size
|
||||
if size = 0 or op2 = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
size := size.abs
|
||||
sml := op2
|
||||
target.resize (size + 1)
|
||||
pp := target.item
|
||||
mul_1 (pp, pp_offset, op1.item, 0, size, sml, carry)
|
||||
cy := carry.item
|
||||
pp [pp_offset + size] := cy
|
||||
size := size + (cy /= 0).to_integer
|
||||
end
|
||||
if sign_product < 0 xor op2 < 0 then
|
||||
target.count := -size
|
||||
else
|
||||
target.count := size
|
||||
end
|
||||
end
|
||||
|
||||
neg (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X)
|
||||
-- Set `rop' to -`op'.
|
||||
local
|
||||
usize: INTEGER_32
|
||||
size: INTEGER_32
|
||||
do
|
||||
usize := op.count
|
||||
if target /= op then
|
||||
size := usize.abs
|
||||
target.resize (size)
|
||||
target.item.copy_data (op.item, 0, 0, size)
|
||||
end
|
||||
target.count := -usize
|
||||
end
|
||||
|
||||
abs (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X)
|
||||
-- Set `rop' to the absolute value of `op'.
|
||||
local
|
||||
size: INTEGER_32
|
||||
do
|
||||
size := op.count.abs
|
||||
if op /= target then
|
||||
target.resize (size)
|
||||
target.item.copy_data (op.item, 0, 0, size)
|
||||
end
|
||||
target.count := size
|
||||
end
|
||||
end
|
||||
155
contrib/ise_library/math/eapml/facilities/integer_x_assignment.e
Normal file
155
contrib/ise_library/math/eapml/facilities/integer_x_assignment.e
Normal file
@@ -0,0 +1,155 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_ASSIGNMENT}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "The object and practice of liberty lies in the limitation of governmental power. - General Douglas MacArthur"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_ASSIGNMENT
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_ASSIGNMENT
|
||||
rename
|
||||
set_str as set_str_special
|
||||
end
|
||||
MP_BASES
|
||||
|
||||
feature
|
||||
|
||||
swap (target: READABLE_INTEGER_X; other_a: READABLE_INTEGER_X)
|
||||
-- Swap the values `rop1' and `rop2' efficiently.
|
||||
local
|
||||
other_size: INTEGER_32
|
||||
other_pointer: SPECIAL [NATURAL_32]
|
||||
do
|
||||
other_size := other_a.count
|
||||
other_pointer := other_a.item
|
||||
other_a.count := target.count
|
||||
other_a.item := target.item
|
||||
target.count := other_size
|
||||
target.item := other_pointer
|
||||
end
|
||||
|
||||
set_str (target: READABLE_INTEGER_X; str: READABLE_STRING_8; base_a: INTEGER)
|
||||
-- Set the value of `rop' from `str', a null-terminated C string in base `base'.
|
||||
-- White space is allowed in the string, and is simply ignored.
|
||||
-- The base may vary from 2 to 62, or if base is 0, then the leading characters
|
||||
-- are used: 0x and 0X for hexadecimal, 0b and 0B for binary, 0 for octal, or
|
||||
-- decimal otherwise.
|
||||
-- For bases up to 36, case is ignored; upper-case and lower-case letters have
|
||||
-- the same value.
|
||||
-- For bases 37 to 62, upper-case letter represent the usual 10..35 while
|
||||
-- lower-case letter represent 36..61.
|
||||
-- This function returns 0 if the entire string is a valid number in base base.
|
||||
-- Otherwise it returns -1.
|
||||
require
|
||||
base_a <= 62
|
||||
base_a >= 2 or base_a = 0
|
||||
local
|
||||
base: INTEGER
|
||||
str_offset: INTEGER
|
||||
s: SPECIAL [NATURAL_8]
|
||||
s_offset: INTEGER
|
||||
begs: INTEGER
|
||||
i: INTEGER
|
||||
xsize: INTEGER
|
||||
c: CHARACTER
|
||||
negative: BOOLEAN
|
||||
digit_value: CHARACTER_STRATEGY
|
||||
str_size: INTEGER
|
||||
dig: NATURAL_8
|
||||
do
|
||||
base := base_a
|
||||
if base > 36 then
|
||||
create {CASE_SENSITIVE_STRATEGY}digit_value
|
||||
else
|
||||
create {CASE_INSENSITIVE_STRATEGY}digit_value
|
||||
end
|
||||
from
|
||||
str_offset := 1
|
||||
c := ' '
|
||||
until
|
||||
not c.is_space or not str.valid_index (str_offset)
|
||||
loop
|
||||
c := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
end
|
||||
if c = '-' then
|
||||
negative := True
|
||||
c := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
end
|
||||
if base = 0 then
|
||||
if digit_value.text_to_number (c.code.to_natural_8) >= 10 then
|
||||
(create {INTEGER_X_STRING_EXCEPTION}).raise
|
||||
end
|
||||
else
|
||||
if digit_value.text_to_number (c.code.to_natural_8) >= base then
|
||||
(create {INTEGER_X_STRING_EXCEPTION}).raise
|
||||
end
|
||||
end
|
||||
if base = 0 then
|
||||
base := 10
|
||||
if c = '0' then
|
||||
base := 8
|
||||
if str.valid_index (str_offset) then
|
||||
c := str [str_offset]
|
||||
end
|
||||
str_offset := str_offset + 1
|
||||
if c = 'x' or c = 'X' then
|
||||
base := 16
|
||||
c := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
elseif c = 'b' or c = 'B' then
|
||||
base := 2
|
||||
c := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
from
|
||||
until
|
||||
c /= '0' and not c.is_space or not str.valid_index (str_offset)
|
||||
loop
|
||||
c := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
end
|
||||
if c.code = 0 then
|
||||
target.count := 0
|
||||
target.item [0] := 0
|
||||
else
|
||||
str_size := str.count - str_offset + 2
|
||||
create s.make_filled (0, str_size)
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= str_size
|
||||
loop
|
||||
if not c.is_space then
|
||||
dig := digit_value.text_to_number (c.code.to_natural_8)
|
||||
if dig.to_integer_32 >= base then
|
||||
(create {INTEGER_X_STRING_EXCEPTION}).raise
|
||||
end
|
||||
s [s_offset] := dig
|
||||
s_offset := s_offset + 1
|
||||
end
|
||||
if str.valid_index (str_offset) then
|
||||
c := str [str_offset]
|
||||
end
|
||||
str_offset := str_offset + 1
|
||||
i := i + 1
|
||||
end
|
||||
str_size := s_offset - begs
|
||||
xsize := (str_size / chars_per_bit_exactly (base)).truncated_to_integer // 32 + 2
|
||||
target.resize (xsize)
|
||||
xsize := set_str_special (target.item, 0, s, begs, str_size, base)
|
||||
if negative then
|
||||
target.count := -xsize
|
||||
else
|
||||
target.count := xsize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
200
contrib/ise_library/math/eapml/facilities/integer_x_comparison.e
Normal file
200
contrib/ise_library/math/eapml/facilities/integer_x_comparison.e
Normal file
@@ -0,0 +1,200 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_COMPARISON}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "The marvel of all history is the patience with which men and women submit to burdens unnecessarily laid upon them by their governments. - U.S. Senator William Borah"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_COMPARISON
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_COMPARISON
|
||||
rename
|
||||
cmp as cmp_special
|
||||
end
|
||||
|
||||
feature
|
||||
|
||||
compare (op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X): INTEGER
|
||||
-- Compare `op1' and `op2'.
|
||||
-- Return a positive value if `op1' > `op2', zero if `op1' = `op2', or a negative value if `op1' < `op2'.
|
||||
local
|
||||
usize: INTEGER_32
|
||||
vsize: INTEGER_32
|
||||
dsize: INTEGER_32
|
||||
asize: INTEGER_32
|
||||
cmp_l: INTEGER_32
|
||||
do
|
||||
usize := op1.count
|
||||
vsize := op2.count
|
||||
dsize := usize - vsize
|
||||
if dsize /= 0 then
|
||||
Result := dsize
|
||||
else
|
||||
asize := usize.abs
|
||||
cmp_l := cmp_special (op1.item, 0, op2.item, 0, asize)
|
||||
if usize >= 0 then
|
||||
Result := cmp_l
|
||||
else
|
||||
Result := -cmp_l
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cmp_si (op1: READABLE_INTEGER_X; op: INTEGER_32): INTEGER
|
||||
-- Compare `op1' and `op2'.
|
||||
-- Return a positive value if `op1' > `op2', zero if `op1' = `op2', or a negative value if `op1' < `op2'.
|
||||
-- Is a macro and will evaluate their arguments more than once.
|
||||
local
|
||||
v_digit: INTEGER_32
|
||||
usize: INTEGER_32
|
||||
vsize: INTEGER_32
|
||||
u_digit: NATURAL_32
|
||||
do
|
||||
v_digit := op
|
||||
usize := op1.count
|
||||
vsize := 0
|
||||
if v_digit > 0 then
|
||||
vsize := 1
|
||||
elseif v_digit < 0 then
|
||||
vsize := -1
|
||||
v_digit := -v_digit
|
||||
end
|
||||
if usize /= vsize then
|
||||
Result := usize - vsize
|
||||
else
|
||||
if usize = 0 then
|
||||
Result := 0
|
||||
else
|
||||
u_digit := op1.item [0]
|
||||
if u_digit = v_digit.to_natural_32 then
|
||||
Result := 0
|
||||
else
|
||||
if u_digit > v_digit.to_natural_32 then
|
||||
Result := usize
|
||||
else
|
||||
Result := -usize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cmp_ui (op1: READABLE_INTEGER_X; op: NATURAL): INTEGER
|
||||
-- Compare `op1' and `op2'.
|
||||
-- Return a positive value if `op1' > `op2', zero if `op1' = `op2', or a negative value if `op1' < `op2'.
|
||||
-- Is a macro and will evaluate their arguments more than once.
|
||||
local
|
||||
un: INTEGER_32
|
||||
ul: NATURAL_32
|
||||
v_digit: NATURAL_32
|
||||
do
|
||||
v_digit := op
|
||||
un := op1.count
|
||||
if un = 0 then
|
||||
if v_digit /= 0 then
|
||||
Result := -1
|
||||
else
|
||||
Result := 0
|
||||
end
|
||||
else
|
||||
if un = 1 then
|
||||
ul := op1.item [0]
|
||||
if ul > v_digit then
|
||||
Result := 1
|
||||
else
|
||||
if ul < v_digit then
|
||||
Result := -1
|
||||
else
|
||||
Result := 0
|
||||
end
|
||||
end
|
||||
else
|
||||
if un > 0 then
|
||||
Result := 1
|
||||
else
|
||||
Result := -1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cmpabs (op1: READABLE_INTEGER_X ;op2: READABLE_INTEGER_X): INTEGER
|
||||
-- Compare the absolute values of `op1' and `op2'.
|
||||
-- Return a positive value if abs(`op1') > abs(`op2'), zero if abs(`op1') = abs(`op2'),
|
||||
-- or a negative value if abs(`op1') < abs(`op2').
|
||||
local
|
||||
usize: INTEGER_32
|
||||
vsize: INTEGER_32
|
||||
dsize: INTEGER_32
|
||||
cmp_l: INTEGER_32
|
||||
i: INTEGER_32
|
||||
x: NATURAL_32
|
||||
y: NATURAL_32
|
||||
do
|
||||
usize := op1.count.abs
|
||||
vsize := op2.count.abs
|
||||
dsize := usize - vsize
|
||||
if dsize /= 0 then
|
||||
Result := dsize
|
||||
else
|
||||
cmp_l := 0
|
||||
from
|
||||
i := usize - 1
|
||||
until
|
||||
i < 0 or cmp_l /= 0
|
||||
loop
|
||||
x := op1.item [i]
|
||||
y := op2.item [i]
|
||||
if x /= y then
|
||||
if x > y then
|
||||
Result := 1
|
||||
else
|
||||
Result := -1
|
||||
end
|
||||
end
|
||||
i := i - 1
|
||||
variant
|
||||
i + 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cmpabs_ui (op1: READABLE_INTEGER_X; op: NATURAL_32): INTEGER
|
||||
-- Compare the absolute values of `op1' and `op2'.
|
||||
-- Return a positive value if abs(`op1') > abs(`op2'), zero if abs(`op1') = abs(`op2'),
|
||||
-- or a negative value if abs(`op1') < abs(`op2').
|
||||
local
|
||||
un: INTEGER_32
|
||||
ul: NATURAL_32
|
||||
v_digit: NATURAL_32
|
||||
do
|
||||
v_digit := op
|
||||
un := op1.count
|
||||
if un = 0 then
|
||||
if v_digit /= 0 then
|
||||
Result := -1
|
||||
else
|
||||
Result := 0
|
||||
end
|
||||
else
|
||||
un := un.abs
|
||||
if un = 1 then
|
||||
ul := op1.item [0]
|
||||
if ul > v_digit then
|
||||
Result := 1
|
||||
else
|
||||
if ul < v_digit then
|
||||
Result := -1
|
||||
else
|
||||
Result := 0
|
||||
end
|
||||
end
|
||||
else
|
||||
Result := 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
429
contrib/ise_library/math/eapml/facilities/integer_x_division.e
Normal file
429
contrib/ise_library/math/eapml/facilities/integer_x_division.e
Normal file
@@ -0,0 +1,429 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_DIVISION}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Collecting more taxes than is absolutely necessary is legalized robbery. - President Calvin Coolidge"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_DIVISION
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_UTILITY
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
SPECIAL_DIVISION
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
tdiv_qr as tdiv_qr_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
INTEGER_X_ARITHMETIC
|
||||
INTEGER_X_ASSIGNMENT
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
|
||||
feature
|
||||
|
||||
fdiv_r_2exp (target: READABLE_INTEGER_X; u: READABLE_INTEGER_X; count: INTEGER)
|
||||
do
|
||||
cfdiv_r_2exp (target, u, count, -1)
|
||||
end
|
||||
|
||||
cdiv_r_2exp (target: READABLE_INTEGER_X; u: READABLE_INTEGER_X; count: INTEGER)
|
||||
do
|
||||
cfdiv_r_2exp (target, u, count, 1)
|
||||
end
|
||||
|
||||
cfdiv_r_2exp (target: READABLE_INTEGER_X; u: READABLE_INTEGER_X; count_a: INTEGER; direction: INTEGER)
|
||||
local
|
||||
usize: INTEGER
|
||||
abs_usize: INTEGER
|
||||
limb_count: INTEGER
|
||||
i: INTEGER
|
||||
up: SPECIAL [NATURAL_32]
|
||||
up_offset: INTEGER
|
||||
wp: SPECIAL [NATURAL_32]
|
||||
wp_offset: INTEGER
|
||||
high: NATURAL_32
|
||||
count: INTEGER
|
||||
returned: BOOLEAN
|
||||
negate: BOOLEAN
|
||||
do
|
||||
create wp.make_empty (0)
|
||||
count := count_a
|
||||
usize := u.count
|
||||
if usize = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
limb_count := count // 32
|
||||
count := count \\ 32
|
||||
abs_usize := usize.abs
|
||||
up := u.item
|
||||
if usize.bit_xor (direction) < 0 and Current = u and abs_usize <= limb_count then
|
||||
returned := True
|
||||
else
|
||||
if usize.bit_xor (direction) < 0 then
|
||||
if Current = u then
|
||||
wp := target.item
|
||||
else
|
||||
i := abs_usize.min (limb_count + 1)
|
||||
target.resize (i)
|
||||
wp := target.item
|
||||
wp.copy_data (up, up_offset, wp_offset, i)
|
||||
if abs_usize <= limb_count then
|
||||
target.count := usize
|
||||
returned := True
|
||||
end
|
||||
end
|
||||
else
|
||||
if abs_usize <= limb_count then
|
||||
negate := True
|
||||
else
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i < limb_count or negate
|
||||
loop
|
||||
negate := up [up_offset + i] /= 0
|
||||
i := i + 1
|
||||
end
|
||||
if not negate then
|
||||
if up [up_offset + limb_count].bit_and (((1).to_natural_32 |<< count) - 1) /= 0 then
|
||||
negate := True
|
||||
else
|
||||
target.count := 0
|
||||
returned := True
|
||||
end
|
||||
end
|
||||
end
|
||||
if not returned and negate then
|
||||
target.resize (limb_count + 1)
|
||||
up := u.item
|
||||
up_offset := 0
|
||||
wp := target.item
|
||||
wp_offset := 0
|
||||
i := abs_usize.min (limb_count + 1)
|
||||
com_n (wp, wp_offset, up, up_offset, i)
|
||||
from
|
||||
until
|
||||
i > limb_count
|
||||
loop
|
||||
wp [wp_offset + i] := high.max_value
|
||||
i := i + 1
|
||||
end
|
||||
incr_u (wp, wp_offset, 1)
|
||||
usize := -usize
|
||||
end
|
||||
end
|
||||
end
|
||||
if not returned then
|
||||
high := wp [wp_offset + limb_count]
|
||||
high := high.bit_and (((1).to_natural_32 |<< count) - 1)
|
||||
wp [wp_offset + limb_count] := high
|
||||
from
|
||||
limb_count := limb_count - 1
|
||||
until
|
||||
high /= 0 or limb_count < 0
|
||||
loop
|
||||
high := wp [wp_offset + limb_count]
|
||||
end
|
||||
if limb_count < 0 then
|
||||
target.count := 0
|
||||
else
|
||||
limb_count := limb_count + 1
|
||||
if usize >= 0 then
|
||||
target.count := limb_count
|
||||
else
|
||||
target.count := -limb_count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mod (target: READABLE_INTEGER_X; dividend: READABLE_INTEGER_X; divisor_a: READABLE_INTEGER_X)
|
||||
local
|
||||
divisor_size: INTEGER
|
||||
temp_divisor: INTEGER_X
|
||||
divisor: READABLE_INTEGER_X
|
||||
do
|
||||
divisor := divisor_a
|
||||
divisor_size := divisor.count
|
||||
if target = divisor then
|
||||
create temp_divisor.make_limbs (divisor_size.abs)
|
||||
temp_divisor.set_from_other (divisor)
|
||||
divisor := temp_divisor
|
||||
end
|
||||
tdiv_r (target, dividend, divisor)
|
||||
if target.count /= 0 then
|
||||
if dividend.count < 0 then
|
||||
if divisor.count < 0 then
|
||||
sub (target, target, divisor)
|
||||
else
|
||||
add (target, target, divisor)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tdiv_q (target: READABLE_INTEGER_X; numerator: READABLE_INTEGER_X; denominator: READABLE_INTEGER_X)
|
||||
local
|
||||
ql: INTEGER
|
||||
ns: INTEGER
|
||||
ds: INTEGER
|
||||
nl: INTEGER
|
||||
dl: INTEGER
|
||||
np: SPECIAL [NATURAL_32]
|
||||
np_offset: INTEGER
|
||||
dp: SPECIAL [NATURAL_32]
|
||||
dp_offset: INTEGER
|
||||
qp: SPECIAL [NATURAL_32]
|
||||
qp_offset: INTEGER
|
||||
rp: SPECIAL [NATURAL_32]
|
||||
rp_offset: INTEGER
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER
|
||||
do
|
||||
ns := numerator.count
|
||||
ds := denominator.count
|
||||
nl := ns.abs
|
||||
dl := ds.abs
|
||||
ql := nl - dl + 1
|
||||
|
||||
if dl = 0 then
|
||||
(create {DIVIDE_BY_ZERO}).raise
|
||||
end
|
||||
if ql <= 0 then
|
||||
target.count := 0
|
||||
else
|
||||
target.resize (ql)
|
||||
qp := target.item
|
||||
create rp.make_filled (0, dl)
|
||||
np := numerator.item
|
||||
dp := denominator.item
|
||||
if dp = qp then
|
||||
create tp.make_filled (0, dl)
|
||||
tp.copy_data (dp, dp_offset, tp_offset, dl)
|
||||
dp := tp
|
||||
end
|
||||
if np = qp then
|
||||
create tp.make_filled (0, nl)
|
||||
tp.copy_data (np, np_offset, tp_offset, nl)
|
||||
np := tp
|
||||
end
|
||||
tdiv_qr_special (qp, qp_offset, rp, rp_offset, np, np_offset, nl, dp, dp_offset, dl)
|
||||
ql := ql - (qp [qp_offset + ql - 1] = 0).to_integer
|
||||
if ns.bit_xor (ds) >= 0 then
|
||||
target.count := ql
|
||||
else
|
||||
target.count := -ql
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tdiv_q_2exp (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X; count_a: INTEGER_32)
|
||||
local
|
||||
usize: INTEGER
|
||||
wsize: INTEGER
|
||||
limb_count: INTEGER
|
||||
wp: SPECIAL [NATURAL_32]
|
||||
wp_offset: INTEGER
|
||||
up: SPECIAL [NATURAL_32]
|
||||
up_offset: INTEGER
|
||||
junk: NATURAL_32
|
||||
count: INTEGER_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
count := count_a
|
||||
usize := op.count
|
||||
limb_count := count // 32
|
||||
wsize := usize.abs - limb_count
|
||||
if wsize <= 0 then
|
||||
target.count := 0
|
||||
else
|
||||
target.resize (wsize)
|
||||
wp := target.item
|
||||
up := op.item
|
||||
count := count \\ 32
|
||||
if count /= 0 then
|
||||
rshift (wp, wp_offset, up, up_offset + limb_count, wsize, count, carry)
|
||||
junk := carry.item
|
||||
wsize := wsize - (wp [wp_offset + wsize - 1] = 0).to_integer
|
||||
else
|
||||
wp.copy_data (up, up_offset + limb_count, wp_offset, wsize)
|
||||
end
|
||||
if usize >= 0 then
|
||||
target.count := wsize
|
||||
else
|
||||
target.count := -wsize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tdiv_qr (target: READABLE_INTEGER_X; remainder: READABLE_INTEGER_X; numerator: READABLE_INTEGER_X; denominator: READABLE_INTEGER_X)
|
||||
local
|
||||
ql: INTEGER_32
|
||||
ns: INTEGER_32
|
||||
ds: INTEGER_32
|
||||
nl: INTEGER_32
|
||||
dl: INTEGER_32
|
||||
temp_dp: SPECIAL [NATURAL_32]
|
||||
temp_np: SPECIAL [NATURAL_32]
|
||||
do
|
||||
ns := numerator.count
|
||||
ds := denominator.count
|
||||
nl := ns.abs
|
||||
dl := ds.abs
|
||||
ql := nl - dl + 1
|
||||
if dl = 0 then
|
||||
(create {DIVIDE_BY_ZERO}).raise
|
||||
end
|
||||
remainder.resize (dl)
|
||||
if ql <= 0 then
|
||||
if numerator /= remainder then
|
||||
remainder.item.copy_data (numerator.item, 0, 0, nl)
|
||||
remainder.count := numerator.count
|
||||
end
|
||||
target.count := 0
|
||||
else
|
||||
target.resize (ql)
|
||||
if denominator = remainder or denominator = Current then
|
||||
create temp_dp.make_empty (dl)
|
||||
temp_dp.copy_data (denominator.item, 0, 0, dl)
|
||||
else
|
||||
temp_dp := denominator.item
|
||||
end
|
||||
if numerator = remainder or numerator = Current then
|
||||
create temp_np.make_empty (nl)
|
||||
temp_np.copy_data (numerator.item, 0, 0, nl)
|
||||
else
|
||||
temp_np := numerator.item
|
||||
end
|
||||
tdiv_qr_special (target.item, 0, remainder.item, 0, temp_np, 0, nl, temp_dp, 0, dl)
|
||||
if target.item [ql - 1] = 0 then
|
||||
ql := ql - 1
|
||||
end
|
||||
remainder.count := normalize (remainder.item, 0, remainder.count)
|
||||
dl := remainder.count
|
||||
if ns.bit_xor (ds) >= 0 then
|
||||
target.count := ql
|
||||
else
|
||||
target.count := -ql
|
||||
end
|
||||
if ns >= 0 then
|
||||
remainder.count := dl
|
||||
else
|
||||
remainder.count := -dl
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tdiv_r (remainder: READABLE_INTEGER_X; numerator: READABLE_INTEGER_X; denominator: READABLE_INTEGER_X)
|
||||
local
|
||||
ql: INTEGER
|
||||
ns: INTEGER
|
||||
ds: INTEGER
|
||||
nl: INTEGER
|
||||
dl: INTEGER
|
||||
np: SPECIAL [NATURAL_32]
|
||||
np_offset: INTEGER
|
||||
dp: SPECIAL [NATURAL_32]
|
||||
dp_offset: INTEGER
|
||||
qp: SPECIAL [NATURAL_32]
|
||||
qp_offset: INTEGER
|
||||
rp: SPECIAL [NATURAL_32]
|
||||
rp_offset: INTEGER
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER
|
||||
do
|
||||
ns := numerator.count
|
||||
ds := denominator.count
|
||||
nl := ns.abs
|
||||
dl := ds.abs
|
||||
ql := nl - dl + 1
|
||||
if dl = 0 then
|
||||
(create {DIVIDE_BY_ZERO}).raise
|
||||
end
|
||||
remainder.resize (dl)
|
||||
if ql <= 0 then
|
||||
if numerator /= remainder then
|
||||
np := numerator.item
|
||||
rp := remainder.item
|
||||
rp.copy_data (np, 0, 0, nl)
|
||||
remainder.count := numerator.count
|
||||
end
|
||||
else
|
||||
create qp.make_filled (0, ql)
|
||||
rp := remainder.item
|
||||
np := numerator.item
|
||||
dp := denominator.item
|
||||
if dp = rp then
|
||||
create tp.make_filled (0, nl)
|
||||
tp.copy_data (np, np_offset, tp_offset, nl)
|
||||
np := tp
|
||||
np_offset := tp_offset
|
||||
end
|
||||
tdiv_qr_special (qp, qp_offset, rp, rp_offset, np, np_offset, nl, dp, dp_offset, dl)
|
||||
dl := normalize (rp, rp_offset, dl)
|
||||
if ns >= 0 then
|
||||
remainder.count := dl
|
||||
else
|
||||
remainder.count := -dl
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tdiv_r_2exp (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X; count: INTEGER)
|
||||
local
|
||||
in_size: INTEGER
|
||||
res_size: INTEGER
|
||||
limb_count: INTEGER
|
||||
in_ptr: SPECIAL [NATURAL_32]
|
||||
in_ptr_offset: INTEGER
|
||||
x: NATURAL_32
|
||||
do
|
||||
in_size := op.count.abs
|
||||
limb_count := count // 32
|
||||
in_ptr := op.item
|
||||
if in_size > limb_count then
|
||||
x := in_ptr [in_ptr_offset + limb_count].bit_and (((1).to_natural_32 |<< (count \\ 32)- 1))
|
||||
if x /= 0 then
|
||||
res_size := limb_count + 1
|
||||
target.resize (res_size)
|
||||
target.item [limb_count] := x
|
||||
else
|
||||
res_size := limb_count
|
||||
res_size := normalize (in_ptr, in_ptr_offset, res_size)
|
||||
target.resize (res_size)
|
||||
limb_count := res_size
|
||||
end
|
||||
else
|
||||
res_size := in_size
|
||||
target.resize (res_size)
|
||||
limb_count := res_size
|
||||
end
|
||||
if target /= op then
|
||||
target.item.copy_data (op.item, 0, 0, limb_count)
|
||||
end
|
||||
if op.count >= 0 then
|
||||
target.count := res_size
|
||||
else
|
||||
target.count := -res_size
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_FACILITIES}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Concentrated power is not rendered harmless by the good intentions of those who create it. - Milton Friedman, Nobel prize-winning economist"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_FACILITIES
|
||||
|
||||
end
|
||||
145
contrib/ise_library/math/eapml/facilities/integer_x_gcd.e
Normal file
145
contrib/ise_library/math/eapml/facilities/integer_x_gcd.e
Normal file
@@ -0,0 +1,145 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_GCD}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "'Need' now means wanting someone else's money. 'Greed' means wanting to keep your own. 'Compassion' is when a politician arranges the transfer. - Joseph Sobran, columnist."
|
||||
|
||||
deferred class
|
||||
INTEGER_X_GCD
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_GCD
|
||||
rename
|
||||
gcd as gcd_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
|
||||
feature
|
||||
|
||||
gcd (g: READABLE_INTEGER_X; u: READABLE_INTEGER_X; v: READABLE_INTEGER_X)
|
||||
local
|
||||
g_zero_bits: INTEGER
|
||||
u_zero_bits: INTEGER
|
||||
v_zero_bits: INTEGER
|
||||
g_zero_limbs: INTEGER
|
||||
u_zero_limbs: INTEGER
|
||||
v_zero_limbs: INTEGER
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER
|
||||
up: SPECIAL [NATURAL_32]
|
||||
up_offset: INTEGER
|
||||
usize: INTEGER
|
||||
vp: SPECIAL [NATURAL_32]
|
||||
vp_offset: INTEGER
|
||||
vsize: INTEGER
|
||||
gsize: INTEGER
|
||||
junk: NATURAL_32
|
||||
cy_limb: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
up := u.item
|
||||
usize := u.count.abs
|
||||
vp := v.item
|
||||
vsize := v.count.abs
|
||||
if usize = 0 then
|
||||
g.count := vsize
|
||||
if g = v then
|
||||
else
|
||||
g.resize (vsize)
|
||||
g.item.copy_data (vp, 0, 0, vsize)
|
||||
end
|
||||
elseif vsize = 0 then
|
||||
g.count := usize
|
||||
if g = u then
|
||||
else
|
||||
g.resize (usize)
|
||||
g.item.copy_data (up, up_offset, 0, usize)
|
||||
end
|
||||
elseif usize = 1 then
|
||||
g.count := 1
|
||||
g.item [0] := gcd_1 (vp, vp_offset, vsize, up [up_offset])
|
||||
elseif vsize = 1 then
|
||||
g.count := 1
|
||||
g.item [0] := gcd_1 (up, up_offset, usize, vp [vp_offset])
|
||||
else
|
||||
from
|
||||
until
|
||||
up [up_offset] /= 0
|
||||
loop
|
||||
up_offset := up_offset + 1
|
||||
end
|
||||
u_zero_limbs := up_offset - 0
|
||||
usize := usize - u_zero_limbs
|
||||
u_zero_bits := trailing_zeros (up [up_offset])
|
||||
tp := up
|
||||
tp_offset := up_offset
|
||||
create up.make_filled (0, usize)
|
||||
if u_zero_bits /= 0 then
|
||||
rshift (up, up_offset, tp, tp_offset, usize, u_zero_bits, carry)
|
||||
junk := carry.item
|
||||
usize := usize - (up [up_offset + usize - 1] = 0).to_integer
|
||||
else
|
||||
up.copy_data (tp, tp_offset, up_offset, usize)
|
||||
end
|
||||
from
|
||||
until
|
||||
vp [vp_offset] /= 0
|
||||
loop
|
||||
vp_offset := vp_offset + 1
|
||||
end
|
||||
v_zero_limbs := vp_offset - 0
|
||||
vsize := vsize - v_zero_limbs
|
||||
v_zero_bits := trailing_zeros (vp [vp_offset])
|
||||
tp := vp
|
||||
tp_offset := vp_offset
|
||||
create vp.make_filled (0, vsize)
|
||||
if v_zero_bits /= 0 then
|
||||
rshift (vp, vp_offset, tp, tp_offset, vsize, v_zero_bits, carry)
|
||||
junk := carry.item
|
||||
vsize := vsize - (vp [vp_offset + vsize - 1] = 0).to_integer
|
||||
else
|
||||
vp.copy_data (tp, tp_offset, vp_offset, vsize)
|
||||
end
|
||||
if u_zero_limbs > v_zero_limbs then
|
||||
g_zero_limbs := v_zero_limbs
|
||||
g_zero_bits := v_zero_bits
|
||||
elseif u_zero_limbs < v_zero_limbs then
|
||||
g_zero_limbs := u_zero_limbs
|
||||
g_zero_bits := u_zero_bits
|
||||
else
|
||||
g_zero_limbs := u_zero_limbs
|
||||
g_zero_bits := u_zero_bits.min (v_zero_bits)
|
||||
end
|
||||
if usize < vsize or (usize = vsize and up [up_offset + usize - 1] < vp [vp_offset + vsize - 1]) then
|
||||
vsize := gcd_special (vp, vp_offset, vp, vp_offset, vsize, up, up_offset, usize)
|
||||
else
|
||||
vsize := gcd_special (vp, vp_offset, up, up_offset, usize, vp, vp_offset, vsize)
|
||||
end
|
||||
gsize := vsize + g_zero_limbs
|
||||
if g_zero_bits /= 0 then
|
||||
gsize := gsize + ((vp [vp_offset + vsize - 1] |>> (32 - g_zero_bits)) /= 0).to_integer
|
||||
g.resize (gsize)
|
||||
g.item.fill_with (0, 0, g_zero_limbs)
|
||||
tp := g.item
|
||||
tp_offset := g_zero_limbs
|
||||
lshift (tp, tp_offset, vp, vp_offset, vsize, g_zero_bits, carry)
|
||||
cy_limb := carry.item
|
||||
if cy_limb /= 0 then
|
||||
tp [tp_offset + vsize] := cy_limb
|
||||
end
|
||||
else
|
||||
g.resize (gsize)
|
||||
g.item.fill_with (0, 0, g_zero_limbs)
|
||||
g.item.copy_data (vp, vp_offset, g_zero_limbs, vsize)
|
||||
end
|
||||
g.count := gsize
|
||||
end
|
||||
ensure
|
||||
g.count /= 0
|
||||
end
|
||||
end
|
||||
335
contrib/ise_library/math/eapml/facilities/integer_x_io.e
Normal file
335
contrib/ise_library/math/eapml/facilities/integer_x_io.e
Normal file
@@ -0,0 +1,335 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_IO}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "I personally call the type of government which can be removed without violence 'democracy,' and the other, 'tyranny.' - Karl Popper"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_IO
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_SIZING
|
||||
SPECIAL_UTILITY
|
||||
LIMB_MANIPULATION
|
||||
|
||||
feature
|
||||
|
||||
output (target: SPECIAL [NATURAL_8]; target_offset: INTEGER; countp: TUPLE [countp: INTEGER]; order: INTEGER; size: INTEGER; endian_a: INTEGER; z: READABLE_INTEGER_X)
|
||||
local
|
||||
zsize: INTEGER
|
||||
zp: SPECIAL [NATURAL_32]
|
||||
zp_offset: INTEGER
|
||||
count: INTEGER
|
||||
numb: INTEGER
|
||||
endian: INTEGER
|
||||
i: INTEGER
|
||||
j: INTEGER
|
||||
limb: NATURAL_32
|
||||
wbitsmask: NATURAL_32
|
||||
wbytes: INTEGER
|
||||
woffset: INTEGER
|
||||
dp: SPECIAL [NATURAL_8]
|
||||
dp_offset: INTEGER
|
||||
lbits: INTEGER
|
||||
wbits: INTEGER
|
||||
zend: INTEGER
|
||||
newlimb: NATURAL_32
|
||||
done: BOOLEAN
|
||||
do
|
||||
endian := endian_a
|
||||
zsize := z.count
|
||||
if zsize = 0 then
|
||||
countp.countp := 0
|
||||
else
|
||||
zsize := zsize.abs
|
||||
zp := z.item
|
||||
numb := 8 * size
|
||||
count := sizeinbase_2exp (zp, zp_offset, zsize, numb)
|
||||
countp.countp := count
|
||||
if endian = 0 then
|
||||
endian := -1
|
||||
end
|
||||
if size = 4 then
|
||||
if order = -1 and endian = -1 then
|
||||
from
|
||||
i := target_offset
|
||||
j := zp_offset
|
||||
until
|
||||
j >= zp_offset + count - 1
|
||||
loop
|
||||
write_limb (zp [zp_offset + j], target, target_offset + i)
|
||||
i := i + 4
|
||||
j := j + 1
|
||||
end
|
||||
done := True
|
||||
elseif order = 1 and endian = -1 then
|
||||
from
|
||||
i := target_offset
|
||||
j := zp_offset + count - 1
|
||||
until
|
||||
j < zp_offset
|
||||
loop
|
||||
write_limb (zp [zp_offset + j], target, target_offset + i)
|
||||
j := j - 1
|
||||
i := i + 4
|
||||
end
|
||||
done := True
|
||||
elseif order = -1 and endian = 1 then
|
||||
from
|
||||
i := target_offset
|
||||
j := zp_offset
|
||||
until
|
||||
j >= zp_offset + count - 1
|
||||
loop
|
||||
write_limb_be (zp [zp_offset + j], target, target_offset + i)
|
||||
j := j + 1
|
||||
i := i + 4
|
||||
end
|
||||
done := True
|
||||
elseif order = 1 and endian = 1 then
|
||||
from
|
||||
i := target_offset
|
||||
j := zp_offset + count - 1
|
||||
until
|
||||
j < zp_offset
|
||||
loop
|
||||
write_limb_be (zp [zp_offset + j], target, target_offset + i)
|
||||
j := j - 1
|
||||
i := i + 4
|
||||
end
|
||||
done := True
|
||||
end
|
||||
end
|
||||
if not done then
|
||||
numb := size * 8
|
||||
wbytes := numb // 8
|
||||
wbits := numb \\ 8
|
||||
wbitsmask := ((1).to_natural_8 |<< wbits) - 1
|
||||
if endian >= 0 then
|
||||
woffset := size
|
||||
else
|
||||
woffset := -size
|
||||
end
|
||||
if order < 0 then
|
||||
woffset := woffset + size
|
||||
else
|
||||
woffset := woffset + -size
|
||||
end
|
||||
dp := target
|
||||
dp_offset := target_offset
|
||||
if order >= 0 then
|
||||
dp_offset := dp_offset + (count - 1) * size
|
||||
else
|
||||
dp_offset := dp_offset + 0
|
||||
end
|
||||
if endian >= 0 then
|
||||
dp_offset := dp_offset + size - 1
|
||||
else
|
||||
dp_offset := dp_offset + 0
|
||||
end
|
||||
zend := zp_offset + zsize
|
||||
lbits := 0
|
||||
limb := 0
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= count
|
||||
loop
|
||||
from
|
||||
j := 0
|
||||
until
|
||||
j >= wbytes
|
||||
loop
|
||||
if lbits >= 8 then
|
||||
dp [dp_offset] := limb.to_natural_8
|
||||
limb := limb |>> 8
|
||||
lbits := lbits - 8
|
||||
else
|
||||
if zp_offset = zend then
|
||||
newlimb := 0
|
||||
else
|
||||
newlimb := zp [zp_offset]
|
||||
zp_offset := zp_offset + 1
|
||||
end
|
||||
dp [dp_offset] := (limb.bit_or (newlimb |<< lbits)).to_natural_8
|
||||
limb := newlimb |>> (8 - lbits)
|
||||
lbits := lbits + limb_bits - 8
|
||||
end
|
||||
dp_offset := dp_offset - endian
|
||||
j := j + 1
|
||||
end
|
||||
if wbits /= 0 then
|
||||
if lbits >= wbits then
|
||||
dp [dp_offset] := limb.bit_and (wbitsmask).to_natural_8
|
||||
limb := limb |>> wbits
|
||||
lbits := lbits - wbits
|
||||
else
|
||||
if zp_offset = zend then
|
||||
newlimb := 0
|
||||
else
|
||||
newlimb := zp [zp_offset]
|
||||
zp_offset := zp_offset + 1
|
||||
end
|
||||
dp [dp_offset] := (limb.bit_or (newlimb |<< lbits)).bit_and (wbitsmask).to_natural_8
|
||||
limb := newlimb |>> (wbits - lbits)
|
||||
lbits := lbits + limb_bits - wbits
|
||||
end
|
||||
end
|
||||
from
|
||||
until
|
||||
j >= size
|
||||
loop
|
||||
dp [dp_offset] := 0
|
||||
dp_offset := dp_offset - endian
|
||||
j := j + 1
|
||||
end
|
||||
dp_offset := dp_offset + woffset
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
input (z: READABLE_INTEGER_X; count: INTEGER; order: INTEGER; size: INTEGER; endian_a: INTEGER; source: SPECIAL [NATURAL_8]; source_offset: INTEGER)
|
||||
local
|
||||
zsize: INTEGER
|
||||
zp: SPECIAL [NATURAL_32]
|
||||
zp_offset: INTEGER
|
||||
i: INTEGER
|
||||
j: INTEGER
|
||||
done: BOOLEAN
|
||||
limb: NATURAL_32
|
||||
byte: NATURAL_32
|
||||
wbitsmask: NATURAL_8
|
||||
numb: INTEGER
|
||||
wbytes: INTEGER
|
||||
woffset: INTEGER
|
||||
dp: SPECIAL [NATURAL_8]
|
||||
dp_offset: INTEGER
|
||||
lbits: INTEGER
|
||||
wbits: INTEGER
|
||||
endian: INTEGER
|
||||
do
|
||||
endian := endian_a
|
||||
zsize := (count * (8 * size) + limb_bits - 1) // limb_bits
|
||||
z.resize (zsize)
|
||||
zp := z.item
|
||||
if endian = 0 then
|
||||
endian := -1
|
||||
end
|
||||
if order = -1 and size = 4 and endian = -1 then
|
||||
from
|
||||
i := zp_offset
|
||||
j := source_offset
|
||||
until
|
||||
i >= count + zp_offset - 1
|
||||
loop
|
||||
zp [zp_offset + i] := read_limb (source, source_offset + j)
|
||||
j := j + 4
|
||||
i := i + 1
|
||||
end
|
||||
done := True
|
||||
elseif order = -1 and size = 4 and endian = 1 then
|
||||
from
|
||||
i := zp_offset
|
||||
j := source_offset
|
||||
until
|
||||
i >= count + zp_offset - 1
|
||||
loop
|
||||
zp [zp_offset + i] := read_limb_be (source, source_offset + j)
|
||||
j := j + 4
|
||||
i := i + 1
|
||||
end
|
||||
done := True
|
||||
elseif order = 1 and size = 4 and endian = -1 then
|
||||
from
|
||||
i := zp_offset + count - 1
|
||||
j := source_offset
|
||||
until
|
||||
i < zp_offset
|
||||
loop
|
||||
zp [zp_offset + i] := read_limb (source, source_offset + j)
|
||||
j := j + 4
|
||||
i := i - 1
|
||||
end
|
||||
done := True
|
||||
end
|
||||
if not done then
|
||||
numb := size * 8
|
||||
wbytes := numb // 8
|
||||
wbits := numb \\ 8
|
||||
wbitsmask := ((1).to_natural_8 |<< wbits) - 1
|
||||
woffset := (numb + 7) // 8
|
||||
if endian >= 0 then
|
||||
woffset := woffset
|
||||
else
|
||||
woffset := -woffset
|
||||
end
|
||||
if order < 0 then
|
||||
woffset := woffset + size
|
||||
else
|
||||
woffset := woffset + -size
|
||||
end
|
||||
dp := source
|
||||
dp_offset := source_offset
|
||||
if order >= 0 then
|
||||
dp_offset := dp_offset + (count - 1) * size
|
||||
else
|
||||
dp_offset := dp_offset + 0
|
||||
end
|
||||
if endian >= 0 then
|
||||
dp_offset := dp_offset + size - 1
|
||||
else
|
||||
dp_offset := dp_offset + 0
|
||||
end
|
||||
limb := 0
|
||||
lbits := 0
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= count
|
||||
loop
|
||||
from
|
||||
j := 0
|
||||
until
|
||||
j >= wbytes
|
||||
loop
|
||||
byte := dp [dp_offset]
|
||||
dp_offset := dp_offset - endian
|
||||
limb := limb.bit_or (byte |<< lbits)
|
||||
lbits := lbits + 8
|
||||
if lbits >= limb_bits then
|
||||
zp [zp_offset] := limb
|
||||
zp_offset := zp_offset + 1
|
||||
lbits := lbits - limb_bits
|
||||
limb := byte |>> (8 - lbits)
|
||||
end
|
||||
j := j + 1
|
||||
end
|
||||
if wbits /= 0 then
|
||||
byte := dp [dp_offset].bit_and (wbitsmask)
|
||||
dp_offset := dp_offset - endian
|
||||
limb := limb.bit_or (byte |<< lbits)
|
||||
lbits := lbits + wbits
|
||||
if lbits >= limb_bits then
|
||||
zp [zp_offset] := limb
|
||||
zp_offset := zp_offset + 1
|
||||
lbits := lbits - limb_bits
|
||||
limb := byte |>> (wbits - lbits)
|
||||
end
|
||||
end
|
||||
dp_offset := dp_offset + woffset
|
||||
i := i + 1
|
||||
end
|
||||
if lbits /= 0 then
|
||||
zp [zp_offset] := limb
|
||||
zp_offset := zp_offset + 1
|
||||
end
|
||||
end
|
||||
zp := z.item
|
||||
zsize := normalize (zp, 0, zsize)
|
||||
z.count := zsize
|
||||
end
|
||||
end
|
||||
1037
contrib/ise_library/math/eapml/facilities/integer_x_logic.e
Normal file
1037
contrib/ise_library/math/eapml/facilities/integer_x_logic.e
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,967 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_NUMBER_THEORY}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Gun registration is a gateway drug. - Mark Gilmore"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_NUMBER_THEORY
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
SPECIAL_ARITHMETIC
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
SPECIAL_DIVISION
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
cmp as cmp_special,
|
||||
tdiv_qr as tdiv_qr_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
SPECIAL_NUMBER_THEORETIC
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
cmp as cmp_special,
|
||||
tdiv_qr as tdiv_qr_special,
|
||||
gcdext as gcdext_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special,
|
||||
invert_gf as invert_gf_special
|
||||
export
|
||||
{NONE}
|
||||
all
|
||||
end
|
||||
INTEGER_X_ACCESS
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
cmp as cmp_special,
|
||||
tdiv_qr as tdiv_qr_special,
|
||||
sizeinbase as sizeinbase_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
end
|
||||
INTEGER_X_ARITHMETIC
|
||||
rename
|
||||
cmp as cmp_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
end
|
||||
INTEGER_X_ASSIGNMENT
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
end
|
||||
INTEGER_X_COMPARISON
|
||||
INTEGER_X_LOGIC
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special
|
||||
end
|
||||
INTEGER_X_DIVISION
|
||||
rename
|
||||
cmp as cmp_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
end
|
||||
INTEGER_X_RANDOM
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
cmp as cmp_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
end
|
||||
INTEGER_X_GCD
|
||||
rename
|
||||
add as add_special,
|
||||
sub as sub_special,
|
||||
mul as mul_special,
|
||||
cmp as cmp_special,
|
||||
tdiv_qr as tdiv_qr_special,
|
||||
bit_xor_lshift as bit_xor_lshift_special,
|
||||
bit_xor as bit_xor_special
|
||||
end
|
||||
INTEGER_X_SIZING
|
||||
|
||||
feature
|
||||
|
||||
millerrabin_test (n: READABLE_INTEGER_X; nm1: READABLE_INTEGER_X; x: READABLE_INTEGER_X; y: READABLE_INTEGER_X; q: READABLE_INTEGER_X; k: INTEGER): INTEGER
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
powm (y, x, q, n)
|
||||
if cmp_ui (y, 1) = 0 or compare (y, nm1) = 0 then
|
||||
Result := 1
|
||||
else
|
||||
from
|
||||
i := 1
|
||||
Result := -1
|
||||
until
|
||||
Result /= -1 or i >= k
|
||||
loop
|
||||
powm_ui (y, y, 2, n)
|
||||
if compare (y, nm1) = 0 then
|
||||
Result := 1
|
||||
elseif cmp_ui (y, 1) = 0 then
|
||||
Result := 0
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
if Result = -1 then
|
||||
Result := 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bin_uiui (target: READABLE_INTEGER_X; n_a: NATURAL_32; k_a: NATURAL_32)
|
||||
-- Compute the binomial coefficient `n' over `k' and store the result in `rop'.
|
||||
local
|
||||
i: NATURAL_32
|
||||
j: NATURAL_32
|
||||
cnt: NATURAL_32
|
||||
n1: CELL [NATURAL_32]
|
||||
n0: CELL [NATURAL_32]
|
||||
k0: NATURAL_32
|
||||
-- t: NATURAL_64
|
||||
k: NATURAL_32
|
||||
n: NATURAL_32
|
||||
rsize: CELL [INTEGER]
|
||||
ralloc: CELL [INTEGER]
|
||||
nacc: CELL [NATURAL_32]
|
||||
kacc: CELL [NATURAL_32]
|
||||
do
|
||||
create n0.put (0)
|
||||
create n1.put (0)
|
||||
create rsize.put (0)
|
||||
create ralloc.put (0)
|
||||
create nacc.put (0)
|
||||
create kacc.put (0)
|
||||
n := n_a
|
||||
k := k_a
|
||||
if n < k then
|
||||
target.count := 0
|
||||
else
|
||||
k := k.min (n - k)
|
||||
if k = 0 then
|
||||
target.count := 1
|
||||
target.item [0] := 1
|
||||
else
|
||||
j := n - k + 1
|
||||
target.item [0] := j
|
||||
target.count := 1
|
||||
ralloc.put (target.capacity)
|
||||
nacc.put (1)
|
||||
kacc.put (1)
|
||||
cnt := 0
|
||||
from
|
||||
i := 2
|
||||
until
|
||||
i > k
|
||||
loop
|
||||
j := j + 1
|
||||
cnt := nacc.item.bit_or (kacc.item).bit_and (1).bit_xor (1)
|
||||
nacc.put (nacc.item |>> cnt.to_integer_32)
|
||||
kacc.put (kacc.item |>> cnt.to_integer_32)
|
||||
umul_ppmm (n1, n0, nacc.item, j)
|
||||
k0 := kacc.item * i
|
||||
if n1.item /= 0 then
|
||||
muldiv (target, 32, rsize, ralloc, nacc, kacc)
|
||||
nacc.put (j)
|
||||
kacc.put (i)
|
||||
else
|
||||
nacc.put (n0.item)
|
||||
kacc.put (k0)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
muldiv (target, 1, rsize, ralloc, nacc, kacc)
|
||||
target.count := rsize.item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
gcdext (g: READABLE_INTEGER_X; s: detachable READABLE_INTEGER_X; t: detachable READABLE_INTEGER_X; a: READABLE_INTEGER_X; b: READABLE_INTEGER_X)
|
||||
-- Set `g' to the greatest common divisor of `a' and `b', and in addition set `s' and `t' to
|
||||
-- coefficients satisfying `a*s + b*t = g'.
|
||||
-- `g' is always positive, even if one or both of `a' and `b' are negative.
|
||||
-- If `t' is NULL then that value is not computed.
|
||||
local
|
||||
asize: INTEGER
|
||||
bsize: INTEGER
|
||||
usize: INTEGER
|
||||
vsize: INTEGER
|
||||
ap: SPECIAL [NATURAL_32]
|
||||
ap_offset: INTEGER
|
||||
bp: SPECIAL [NATURAL_32]
|
||||
bp_offset: INTEGER
|
||||
up: SPECIAL [NATURAL_32]
|
||||
up_offset: INTEGER
|
||||
vp: SPECIAL [NATURAL_32]
|
||||
vp_offset: INTEGER
|
||||
gsize: INTEGER
|
||||
ssize: INTEGER
|
||||
tmp_ssize: TUPLE [tmp_ssize: INTEGER]
|
||||
gp: SPECIAL [NATURAL_32]
|
||||
sp: SPECIAL [NATURAL_32]
|
||||
tmp_gp: SPECIAL [NATURAL_32]
|
||||
tmp_gp_offset: INTEGER
|
||||
tmp_sp: SPECIAL [NATURAL_32]
|
||||
tmp_sp_offset: INTEGER
|
||||
u: READABLE_INTEGER_X
|
||||
v: READABLE_INTEGER_X
|
||||
ss: detachable READABLE_INTEGER_X
|
||||
tt: detachable READABLE_INTEGER_X
|
||||
gtmp: INTEGER_X
|
||||
stmp: INTEGER_X
|
||||
x: INTEGER_X
|
||||
do
|
||||
create tmp_ssize
|
||||
asize := a.count.abs
|
||||
bsize := b.count.abs
|
||||
ap := a.item
|
||||
bp := b.item
|
||||
if asize > bsize or (asize = bsize and cmp_special (ap, ap_offset, bp, bp_offset, asize) > 0) then
|
||||
usize := asize
|
||||
vsize := bsize
|
||||
create up.make_filled (0, usize + 1)
|
||||
create vp.make_filled (0, vsize + 1)
|
||||
up.copy_data (ap, ap_offset, up_offset, usize)
|
||||
vp.copy_data (bp, bp_offset, vp_offset, vsize)
|
||||
u := a
|
||||
v := b
|
||||
ss := s
|
||||
tt := t
|
||||
else
|
||||
usize := bsize
|
||||
vsize := asize
|
||||
create up.make_filled (0, usize + 1)
|
||||
create vp.make_filled (0, vsize + 1)
|
||||
up.copy_data (bp, bp_offset, up_offset, usize)
|
||||
vp.copy_data (ap, ap_offset, vp_offset, vsize)
|
||||
u := b
|
||||
v := a
|
||||
ss := t
|
||||
tt := s
|
||||
end
|
||||
create tmp_gp.make_filled (0, usize + 1)
|
||||
create tmp_sp.make_filled (0, usize + 1)
|
||||
if vsize = 0 then
|
||||
tmp_sp [tmp_sp_offset] := 1
|
||||
tmp_ssize.tmp_ssize := 1
|
||||
tmp_gp.copy_data (up, up_offset, tmp_gp_offset, usize)
|
||||
gsize := usize
|
||||
else
|
||||
gsize := gcdext_special (tmp_gp, tmp_gp_offset, tmp_sp, tmp_sp_offset, tmp_ssize, up, up_offset, usize, vp, vp_offset, vsize)
|
||||
end
|
||||
ssize := tmp_ssize.tmp_ssize.abs
|
||||
create gtmp
|
||||
gtmp.item := tmp_gp
|
||||
gtmp.count := gsize
|
||||
create stmp
|
||||
stmp.item := tmp_sp
|
||||
if tmp_ssize.tmp_ssize.bit_xor (u.count) >= 0 then
|
||||
stmp.count := ssize
|
||||
else
|
||||
stmp.count := -ssize
|
||||
end
|
||||
if attached {READABLE_INTEGER_X} tt as tt_l then
|
||||
if v.count = 0 then
|
||||
tt_l.count := 0
|
||||
else
|
||||
create x.make_limbs (ssize + usize + 1)
|
||||
mul (x, stmp, u)
|
||||
sub (x, gtmp, x)
|
||||
tdiv_q (tt_l, x, v)
|
||||
end
|
||||
end
|
||||
if attached {READABLE_INTEGER_X} ss as ss_l then
|
||||
ss_l.resize (ssize)
|
||||
sp := ss_l.item
|
||||
sp.copy_data (tmp_sp, tmp_sp_offset, 0, ssize)
|
||||
ss_l.count := stmp.count
|
||||
end
|
||||
g.resize (gsize)
|
||||
gp := g.item
|
||||
gp.copy_data (tmp_gp, tmp_gp_offset, 0, gsize)
|
||||
g.count := gsize
|
||||
end
|
||||
|
||||
invert (target: READABLE_INTEGER_X; x: READABLE_INTEGER_X; n: READABLE_INTEGER_X): BOOLEAN
|
||||
local
|
||||
gcd_l: INTEGER_X
|
||||
tmp: INTEGER_X
|
||||
xsize: INTEGER_32
|
||||
nsize: INTEGER_32
|
||||
size: INTEGER_32
|
||||
do
|
||||
xsize := x.count.abs
|
||||
nsize := n.count.abs
|
||||
size := xsize.max (nsize) + 1
|
||||
if xsize = 0 or (nsize = 1 and n.item [0] = 1) then
|
||||
Result := False
|
||||
else
|
||||
create gcd_l.make_limbs (size)
|
||||
create tmp.make_limbs (size)
|
||||
gcdext (gcd_l, tmp, void, x, n)
|
||||
if gcd_l.count /= 1 or gcd_l.item [0] /= 1 then
|
||||
Result := False
|
||||
else
|
||||
if tmp.count < 0 then
|
||||
if n.count < 0 then
|
||||
sub (target, tmp, n)
|
||||
else
|
||||
add (target, tmp, n)
|
||||
end
|
||||
else
|
||||
target.copy (tmp)
|
||||
end
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
millerrabin (source: READABLE_INTEGER_X; reps: INTEGER): INTEGER
|
||||
local
|
||||
r: INTEGER
|
||||
nm1: INTEGER_X
|
||||
nm3: INTEGER_X
|
||||
x: INTEGER_X
|
||||
y: INTEGER_X
|
||||
q: INTEGER_X
|
||||
k: INTEGER
|
||||
is_prime: INTEGER
|
||||
rstate: MERSENNE_TWISTER_RNG
|
||||
do
|
||||
create nm1.make_limbs (source.count + 1)
|
||||
sub_ui (nm1, source, 1)
|
||||
create x.make_limbs (source.count + 1)
|
||||
create y.make_limbs (2 * source.count)
|
||||
x.set_from_natural_32 (210)
|
||||
powm (y, x, nm1, source)
|
||||
if cmp_ui (y, 1) /= 0 then
|
||||
Result := 0
|
||||
else
|
||||
create q.make_limbs (source.count)
|
||||
k := bit_scan_1 (nm1, 0)
|
||||
tdiv_q_2exp (q, nm1, k)
|
||||
create nm3.make_limbs (source.count + 1)
|
||||
sub_ui (nm3, source, 3)
|
||||
create rstate.make
|
||||
is_prime := 1
|
||||
from
|
||||
r := 0
|
||||
until
|
||||
r >= reps or is_prime = 0
|
||||
loop
|
||||
urandomm (x, rstate, nm3)
|
||||
add_ui (x, x, 2)
|
||||
is_prime := millerrabin_test (source, nm1, x, y, q, k)
|
||||
r := r + 1
|
||||
end
|
||||
Result := is_prime
|
||||
end
|
||||
end
|
||||
|
||||
powm (r: READABLE_INTEGER_X; b_a: READABLE_INTEGER_X; e: READABLE_INTEGER_X; m: READABLE_INTEGER_X)
|
||||
local
|
||||
xp: SPECIAL [NATURAL_32]
|
||||
xp_offset: INTEGER
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER
|
||||
qp: SPECIAL [NATURAL_32]
|
||||
qp_offset: INTEGER
|
||||
gp: SPECIAL [NATURAL_32]
|
||||
gp_offset: INTEGER
|
||||
this_gp: SPECIAL [NATURAL_32]
|
||||
this_gp_offset: INTEGER
|
||||
bp: SPECIAL [NATURAL_32]
|
||||
bp_offset: INTEGER
|
||||
ep: SPECIAL [NATURAL_32]
|
||||
ep_offset: INTEGER
|
||||
mp: SPECIAL [NATURAL_32]
|
||||
mp_offset: INTEGER
|
||||
bn: INTEGER
|
||||
es: INTEGER
|
||||
en: INTEGER
|
||||
mn: INTEGER
|
||||
xn: INTEGER
|
||||
invm: NATURAL_32
|
||||
c: NATURAL_32
|
||||
enb: INTEGER
|
||||
i: INTEGER
|
||||
big_k: INTEGER
|
||||
j: INTEGER
|
||||
l: INTEGER
|
||||
small_k: INTEGER
|
||||
m_zero_cnt: INTEGER
|
||||
e_zero_cnt: INTEGER
|
||||
sh: INTEGER
|
||||
use_redc: BOOLEAN
|
||||
new_b: INTEGER_X
|
||||
b: READABLE_INTEGER_X
|
||||
new_mp: SPECIAL [NATURAL_32]
|
||||
new_mp_offset: INTEGER
|
||||
junk: NATURAL_32
|
||||
cy: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
b := b_a
|
||||
mp := m.item
|
||||
mn := m.count.abs
|
||||
if mn = 0 then
|
||||
(create {DIVIDE_BY_ZERO}).raise
|
||||
end
|
||||
es := e.count
|
||||
if es = 0 then
|
||||
if mn = 1 and mp [mp_offset] = 1 then
|
||||
r.count := 0
|
||||
else
|
||||
r.count := 1
|
||||
end
|
||||
r.item [0] := 1
|
||||
else
|
||||
if es < 0 then
|
||||
create new_b.make_limbs (mn + 1)
|
||||
if not invert (new_b, b, m) then
|
||||
(create {INVERSE_EXCEPTION}).raise
|
||||
end
|
||||
b := new_b
|
||||
es := -es
|
||||
end
|
||||
en := es
|
||||
use_redc := (mn < 170) and (mp [mp_offset] \\ 2 /= 0)
|
||||
if use_redc then
|
||||
invm := modlimb_invert (mp [mp_offset])
|
||||
invm := 0 - invm
|
||||
else
|
||||
m_zero_cnt := leading_zeros (mp [mp_offset + mn - 1])
|
||||
if m_zero_cnt /= 0 then
|
||||
create new_mp.make_filled (0, mn)
|
||||
lshift (new_mp, new_mp_offset, mp, mp_offset, mn, m_zero_cnt, carry)
|
||||
junk := carry.item
|
||||
mp := new_mp
|
||||
mp_offset := new_mp_offset
|
||||
end
|
||||
end
|
||||
e_zero_cnt := leading_zeros (e.item [en - 1])
|
||||
enb := en * limb_bits - e_zero_cnt
|
||||
small_k := 1
|
||||
big_k := 2
|
||||
from
|
||||
until
|
||||
small_k = 10 or 2 * enb <= big_k * (2 + small_k * (3 + small_k))
|
||||
loop
|
||||
small_k := small_k + 1
|
||||
big_k := big_k * 2
|
||||
end
|
||||
create tp.make_filled (0, 2 * mn)
|
||||
create qp.make_filled (0, mn + 1)
|
||||
create gp.make_filled (0, big_k // 2 * mn)
|
||||
bn := b.count.abs
|
||||
bp := b.item
|
||||
if bn > mn or (bn = mn and cmp_special (bp, bp_offset, mp, mp_offset, mn) >= 0) then
|
||||
if use_redc then
|
||||
reduce (tp, tp_offset + mn, bp, bp_offset, bn, mp, mp_offset, mn)
|
||||
tp.fill_with (0, tp_offset, mn - tp_offset - 1)
|
||||
tdiv_qr_special (qp, qp_offset, gp, gp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
else
|
||||
reduce (gp, gp_offset, bp, bp_offset, bn, mp, mp_offset, mn)
|
||||
end
|
||||
else
|
||||
if use_redc then
|
||||
tp.copy_data (bp, bp_offset, tp_offset + mn, bn)
|
||||
tdiv_qr_special (qp, qp_offset, gp, gp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
else
|
||||
gp.copy_data (bp, bp_offset, gp_offset, bn)
|
||||
gp.fill_with (0, gp_offset + bn, mn - bn - gp_offset - 1)
|
||||
end
|
||||
end
|
||||
create xp.make_filled (0, mn)
|
||||
sqr_n (tp, tp_offset, gp, gp_offset, mn)
|
||||
if use_redc then
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
this_gp := gp
|
||||
this_gp_offset := gp_offset
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i >= big_k // 2
|
||||
loop
|
||||
mul_n (tp, tp_offset, this_gp, this_gp_offset, xp, xp_offset, mn)
|
||||
this_gp_offset := this_gp_offset + mn
|
||||
if use_redc then
|
||||
redc_basecase (this_gp, this_gp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, this_gp, this_gp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
ep := e.item
|
||||
i := en - 1
|
||||
c := ep [ep_offset + i]
|
||||
sh := limb_bits - e_zero_cnt
|
||||
sh := sh - small_k
|
||||
if sh < 0 then
|
||||
if i > 0 then
|
||||
i := i - 1
|
||||
c := c |<< (-sh)
|
||||
sh := sh + limb_bits
|
||||
c := c.bit_or (ep [ep_offset + i] |>> sh)
|
||||
end
|
||||
else
|
||||
c := c |>> sh
|
||||
end
|
||||
from
|
||||
j := 0
|
||||
until
|
||||
c \\ 2 /= 0
|
||||
loop
|
||||
c := c |>> 1
|
||||
j := j + 1
|
||||
end
|
||||
xp.copy_data (gp, gp_offset + mn * (c |>> 1).to_integer_32, xp_offset, mn)
|
||||
from
|
||||
j := j - 1
|
||||
until
|
||||
j < 0
|
||||
loop
|
||||
sqr_n (tp, tp_offset, xp, xp_offset, mn)
|
||||
if use_redc then
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
j := j - 1
|
||||
end
|
||||
from
|
||||
until
|
||||
i <= 0 and sh <= 0
|
||||
loop
|
||||
c := ep [ep_offset + i]
|
||||
l := small_k
|
||||
sh := sh - l
|
||||
if sh < 0 then
|
||||
if i > 0 then
|
||||
i := i - 1
|
||||
c := c |<< (-sh)
|
||||
sh := sh + limb_bits
|
||||
c := c.bit_or (ep [ep_offset + i] |>> sh)
|
||||
else
|
||||
l := l + sh
|
||||
end
|
||||
else
|
||||
c := c |>> sh
|
||||
end
|
||||
c := c.bit_and (((1).to_natural_32 |<< l) - 1)
|
||||
from
|
||||
until
|
||||
(c |>> (l - 1)) /= 0 or (i <= 0 and sh <= 0)
|
||||
loop
|
||||
sqr_n (tp, tp_offset, xp, xp_offset, mn)
|
||||
if use_redc then
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
if sh /= 0 then
|
||||
sh := sh - 1
|
||||
c := (c |<< 1) + ((ep [ep_offset + i] |>> sh).bit_and (1))
|
||||
else
|
||||
i := i - 1
|
||||
sh := limb_bits - 1
|
||||
c := (c |<< 1) + (ep [ep_offset + i] |>> sh)
|
||||
end
|
||||
end
|
||||
if c /= 0 then
|
||||
from
|
||||
j := 0
|
||||
until
|
||||
c \\ 2 /= 0
|
||||
loop
|
||||
c := c |>> 1
|
||||
j := j + 1
|
||||
end
|
||||
l := l - j
|
||||
from
|
||||
l := l - 1
|
||||
until
|
||||
l < 0
|
||||
loop
|
||||
sqr_n (tp, tp_offset, xp, xp_offset, mn)
|
||||
if use_redc then
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
l := l - 1
|
||||
end
|
||||
mul_n (tp, tp_offset, xp, xp_offset, gp, gp_offset + mn * (c |>> 1).to_integer_32, mn)
|
||||
if use_redc then
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
else
|
||||
j := l
|
||||
end
|
||||
from
|
||||
j := j - 1
|
||||
until
|
||||
j < 0
|
||||
loop
|
||||
sqr_n (tp, tp_offset, xp, xp_offset, mn)
|
||||
if use_redc then
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn)
|
||||
end
|
||||
j := j - 1
|
||||
end
|
||||
end
|
||||
if use_redc then
|
||||
tp.copy_data (xp, xp_offset, tp_offset, mn)
|
||||
tp.fill_with (0, tp_offset + mn, tp_offset + mn + mn - 1)
|
||||
redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset)
|
||||
if cmp_special (xp, xp_offset, mp, mp_offset, mn) >= 0 then
|
||||
sub_n (xp, xp_offset, xp, xp_offset, mp, mp_offset, mn, carry)
|
||||
junk := carry.item
|
||||
end
|
||||
else
|
||||
if m_zero_cnt /= 0 then
|
||||
lshift (tp, tp_offset, xp, xp_offset, mn, m_zero_cnt, carry)
|
||||
cy := carry.item
|
||||
tp [tp_offset + mn] := cy
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, mn + (cy /= 0).to_integer, mp, mp_offset, mn)
|
||||
rshift (xp, xp_offset, xp, xp_offset, mn, m_zero_cnt, carry)
|
||||
junk := carry.item
|
||||
end
|
||||
end
|
||||
xn := mn
|
||||
xn := normalize (xp, xp_offset, xn)
|
||||
if ep [ep_offset].bit_and (1) /= 0 and b.count < 0 and xn /= 0 then
|
||||
mp := m.item
|
||||
sub_special (xp, xp_offset, mp, mp_offset, mn, xp, xp_offset, xn, carry)
|
||||
junk := carry.item
|
||||
xn := mn
|
||||
xn := normalize (xp, xp_offset, xn)
|
||||
end
|
||||
r.resize (xn)
|
||||
r.count := xn
|
||||
r.item.copy_data (xp, xp_offset, 0, xn)
|
||||
end
|
||||
end
|
||||
|
||||
powm_ui (target: READABLE_INTEGER_X; b: READABLE_INTEGER_X; el: NATURAL_32; m: READABLE_INTEGER_X)
|
||||
local
|
||||
xp: SPECIAL [NATURAL_32]
|
||||
xp_offset: INTEGER
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER
|
||||
qp: SPECIAL [NATURAL_32]
|
||||
qp_offset: INTEGER
|
||||
mp: SPECIAL [NATURAL_32]
|
||||
mp_offset: INTEGER
|
||||
bp: SPECIAL [NATURAL_32]
|
||||
bp_offset: INTEGER
|
||||
xn: INTEGER
|
||||
tn: INTEGER
|
||||
mn: INTEGER
|
||||
bn: INTEGER
|
||||
m_zero_count: INTEGER
|
||||
c: INTEGER
|
||||
e: NATURAL_32
|
||||
new_mp: SPECIAL [NATURAL_32]
|
||||
junk: NATURAL_32
|
||||
new_bp: SPECIAL [NATURAL_32]
|
||||
cy: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
mp := m.item
|
||||
mn := m.count.abs
|
||||
if mn = 0 then
|
||||
(create {DIVIDE_BY_ZERO}).raise
|
||||
end
|
||||
if el = 0 then
|
||||
target.count := (not (mn = 1 and then mp [mp_offset] = 1)).to_integer
|
||||
target.item [0] := 1
|
||||
else
|
||||
m_zero_count := leading_zeros (mp [mp_offset + mn - 1])
|
||||
if m_zero_count /= 0 then
|
||||
create new_mp.make_filled (0, mn)
|
||||
lshift (new_mp, 0, mp, mp_offset, mn, m_zero_count, carry)
|
||||
junk := carry.item
|
||||
mp := new_mp
|
||||
end
|
||||
bn := b.count.abs
|
||||
bp := b.item
|
||||
if bn > mn then
|
||||
create new_bp.make_filled (0, mn)
|
||||
reduce (new_bp, 0, bp, bp_offset, bn, mp, mp_offset, mn)
|
||||
bp := new_bp
|
||||
bn := mn
|
||||
bn := normalize (bp, 0, bn)
|
||||
end
|
||||
if bn = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
create tp.make_filled (0, 2 * mn + 1)
|
||||
create xp.make_filled (0, mn)
|
||||
create qp.make_filled (0, mn + 1)
|
||||
xp.copy_data (bp, bp_offset, xp_offset, bn)
|
||||
xn := bn
|
||||
e := el
|
||||
c := leading_zeros (e)
|
||||
e := (e |<< c) |<< 1
|
||||
c := limb_bits - 1 - c
|
||||
if c = 0 and then xn = mn and cmp_special (xp, xp_offset, mp, mp_offset, mn) >= 0 then
|
||||
sub_n (xp, xp_offset, xp, xp_offset, mp, mp_offset, mn, carry)
|
||||
junk := carry.item
|
||||
else
|
||||
from
|
||||
until
|
||||
c = 0
|
||||
loop
|
||||
sqr_n (tp, tp_offset, xp, xp_offset, xn)
|
||||
tn := 2 * xn
|
||||
tn := tn - (tp [tp_offset + tn - 1] = 0).to_integer
|
||||
if tn < mn then
|
||||
xp.copy_data (tp, tp_offset, xp_offset, tn)
|
||||
xn := tn
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, tn, mp, mp_offset, mn)
|
||||
xn := mn
|
||||
end
|
||||
if e.to_integer_32 < 0 then
|
||||
mul_special (tp, tp_offset, xp, xp_offset, xn, bp, bp_offset, bn, carry)
|
||||
junk := carry.item
|
||||
tn := xn + bn
|
||||
tn := tn - (tp [tp_offset + tn - 1] = 0).to_integer
|
||||
if tn < mn then
|
||||
xp.copy_data (tp, tp_offset, xp_offset, tn)
|
||||
xn := tn
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, tn, mp, mp_offset, mn)
|
||||
xn := mn
|
||||
end
|
||||
end
|
||||
e := e |<< 1
|
||||
c := c - 1
|
||||
end
|
||||
end
|
||||
if m_zero_count /= 0 then
|
||||
lshift (tp, tp_offset, xp, xp_offset, xn, m_zero_count, carry)
|
||||
cy := carry.item
|
||||
tp [tp_offset + xn] := cy
|
||||
xn := xn + (cy /= 0).to_integer
|
||||
if xn < mn then
|
||||
xp.copy_data (tp, tp_offset, xp_offset, xn)
|
||||
else
|
||||
tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, xn, mp, mp_offset, mn)
|
||||
xn := mn
|
||||
end
|
||||
rshift (xp, xp_offset, xp, xp_offset, xn, m_zero_count, carry)
|
||||
junk := carry.item
|
||||
end
|
||||
xn := normalize (xp, xp_offset, xn)
|
||||
if el.bit_test (0) and b.count < 0 and xn /= 0 then
|
||||
mp := m.item
|
||||
mp_offset := 0
|
||||
sub_special (xp, xp_offset, mp, mp_offset, mn, xp, xp_offset, xn, carry)
|
||||
junk := carry.item
|
||||
xn := mn
|
||||
xn := normalize (xp, xp_offset, xn)
|
||||
end
|
||||
target.resize (xn)
|
||||
target.count := xn
|
||||
target.item.copy_data (xp, xp_offset, 0, xn)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
probab_prime_isprime (t: NATURAL_32): BOOLEAN
|
||||
local
|
||||
q: NATURAL_32
|
||||
r: NATURAL_32
|
||||
d: NATURAL_32
|
||||
do
|
||||
if t < 3 or not t.bit_test (0) then
|
||||
Result := t = 2
|
||||
else
|
||||
from
|
||||
d := 3
|
||||
r := 1
|
||||
q := d
|
||||
until
|
||||
Result or r = 0
|
||||
loop
|
||||
q := t // d
|
||||
r := t - q * d
|
||||
Result := (q < d)
|
||||
d := d + 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
probab_prime_p (op1_a: READABLE_INTEGER_X; reps: INTEGER): INTEGER
|
||||
local
|
||||
r: NATURAL_32
|
||||
n2: INTEGER_X
|
||||
is_prime: BOOLEAN
|
||||
op1: READABLE_INTEGER_X
|
||||
done: BOOLEAN
|
||||
ln2: NATURAL_32
|
||||
q: NATURAL_32
|
||||
p1: CELL [NATURAL_32]
|
||||
p0: CELL [NATURAL_32]
|
||||
p: NATURAL_32
|
||||
primes: SPECIAL [NATURAL_32]
|
||||
nprimes: INTEGER
|
||||
do
|
||||
create p1.put (0)
|
||||
create p0.put (0)
|
||||
create primes.make_filled (0, 15)
|
||||
op1 := op1_a
|
||||
create n2
|
||||
if cmp_ui (op1, 1_000_000) <= 0 then
|
||||
if cmpabs_ui (op1, 1_000_000) <= 0 then
|
||||
is_prime := probab_prime_isprime (op1.as_natural_32)
|
||||
if is_prime then
|
||||
Result := 2
|
||||
else
|
||||
Result := 0
|
||||
end
|
||||
done := True
|
||||
else
|
||||
n2.item := op1.item
|
||||
n2.count := -op1.count
|
||||
op1 := n2
|
||||
end
|
||||
end
|
||||
if not done then
|
||||
if not op1.as_natural_32.bit_test (0) then
|
||||
done := True
|
||||
end
|
||||
end
|
||||
if not done then
|
||||
r := preinv_mod_1 (op1.item, 0, op1.count, pp, pp_inverted)
|
||||
if r \\ 3 = 0 or r \\ 5 = 0 or r \\ 7 = 0 or r \\ 11 = 0 or r \\ 13 = 0 or r \\ 17 = 0 or r \\ 19 = 0 or r \\ 23 = 0 or r \\ 29 = 0 then
|
||||
Result := 0
|
||||
done := True
|
||||
end
|
||||
end
|
||||
if not done then
|
||||
nprimes := 0
|
||||
p := 1
|
||||
ln2 := sizeinbase (op1, 2).to_natural_32
|
||||
from
|
||||
q := pp_first_omitted.to_natural_32
|
||||
until
|
||||
q >= ln2 or done
|
||||
loop
|
||||
if probab_prime_isprime (q) then
|
||||
umul_ppmm (p1, p0, p, q)
|
||||
if p1.item /= 0 then
|
||||
r := modexact_1c_odd (op1.item, 0, op1.count, p, 0)
|
||||
from
|
||||
nprimes := nprimes - 1
|
||||
until
|
||||
nprimes < 0 or done
|
||||
loop
|
||||
if r \\ primes [nprimes] = 0 then
|
||||
Result := 0
|
||||
done := True
|
||||
end
|
||||
nprimes := nprimes - 1
|
||||
end
|
||||
p := q
|
||||
nprimes := 0
|
||||
else
|
||||
p := p0.item
|
||||
end
|
||||
primes [nprimes] := q
|
||||
nprimes := nprimes + 1
|
||||
end
|
||||
q := q + 2
|
||||
end
|
||||
end
|
||||
if not done then
|
||||
Result := millerrabin (op1, reps)
|
||||
end
|
||||
end
|
||||
|
||||
pp: NATURAL_32 = 0xC0CFD797
|
||||
pp_inverted: NATURAL_32 = 0x53E5645C
|
||||
pp_first_omitted: INTEGER = 31
|
||||
|
||||
reduce (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; ap_count: INTEGER; mp: SPECIAL [NATURAL_32]; mp_offset: INTEGER; mp_count: INTEGER)
|
||||
local
|
||||
tmp: SPECIAL [NATURAL_32]
|
||||
do
|
||||
create tmp.make_filled (0, ap_count - mp_count + 1)
|
||||
tdiv_qr_special (tmp, 0, target, target_offset, ap, ap_offset, ap_count, mp, mp_offset, mp_count)
|
||||
end
|
||||
|
||||
muldiv (target: READABLE_INTEGER_X; inc: INTEGER_32; rsize: CELL [INTEGER_32]; ralloc: CELL [INTEGER_32]; nacc: CELL [NATURAL_32]; kacc: CELL [NATURAL_32])
|
||||
local
|
||||
new_ralloc: INTEGER_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
if rsize.item <= ralloc.item then
|
||||
new_ralloc := ralloc.item + inc
|
||||
target.resize (new_ralloc)
|
||||
ralloc.put (new_ralloc)
|
||||
end
|
||||
mul_1 (target.item, 0, target.item, 0, rsize.item, nacc.item, carry)
|
||||
target.item [rsize.item] := carry.item
|
||||
divexact_1 (target.item, 0, target.item, 0, rsize.item + 1, kacc.item)
|
||||
if target.item [rsize.item] /= 0 then
|
||||
rsize.put (rsize.item + 1)
|
||||
end
|
||||
end
|
||||
|
||||
invert_gf (target: READABLE_INTEGER_X op1: READABLE_INTEGER_X op2: READABLE_INTEGER_X)
|
||||
require
|
||||
not op1.is_negative
|
||||
not op2.is_negative
|
||||
local
|
||||
target_special: SPECIAL [NATURAL_32]
|
||||
op2_count: INTEGER
|
||||
do
|
||||
target.resize (op2.count)
|
||||
op2_count := op2.count
|
||||
target_special := target.item
|
||||
invert_gf_special (target_special, 0, op1.item, 0, op1.count, op2.item, 0, op2_count)
|
||||
target.count := normalize (target_special, 0, op2_count)
|
||||
end
|
||||
end
|
||||
108
contrib/ise_library/math/eapml/facilities/integer_x_random.e
Normal file
108
contrib/ise_library/math/eapml/facilities/integer_x_random.e
Normal file
@@ -0,0 +1,108 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_RANDOM}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Letting lawyers make laws is like letting doctors make diseases. - Anonymous"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_RANDOM
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
LIMB_MANIPULATION
|
||||
SPECIAL_COMPARISON
|
||||
SPECIAL_ARITHMETIC
|
||||
SPECIAL_UTILITY
|
||||
|
||||
feature
|
||||
|
||||
urandomb (target: READABLE_INTEGER_X; state: RANDOM_NUMBER_GENERATOR; nbits: INTEGER)
|
||||
-- Generate a uniformly distributed random integer in the range 0 to 2^`n'-1, inclusive.
|
||||
-- `state' must be initialized by calling one of the randinit functions before invoking this function.
|
||||
local
|
||||
size: INTEGER_32
|
||||
do
|
||||
size := bits_to_limbs (nbits)
|
||||
target.resize (size)
|
||||
state.randget (target.item, 0, nbits)
|
||||
size := normalize (target.item, 0, size)
|
||||
target.count := size
|
||||
ensure
|
||||
target.bits <= nbits
|
||||
end
|
||||
|
||||
urandomm (target: READABLE_INTEGER_X; state: RANDOM_NUMBER_GENERATOR; n: READABLE_INTEGER_X)
|
||||
-- Generate a uniform random integer in the range 0 to n-1, inclusive.
|
||||
-- `state' must be initialized by calling one of the randinit functions before invoking this function.
|
||||
local
|
||||
rp: SPECIAL [NATURAL_32]
|
||||
rp_offset: INTEGER
|
||||
np: SPECIAL [NATURAL_32]
|
||||
np_offset: INTEGER
|
||||
nlast: INTEGER
|
||||
nbits: INTEGER
|
||||
size: INTEGER
|
||||
count: INTEGER
|
||||
pow2: BOOLEAN
|
||||
cmp_l: INTEGER
|
||||
overlap: BOOLEAN
|
||||
junk: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
size := n.count.abs
|
||||
if size = 0 then
|
||||
(create {DIVIDE_BY_ZERO}).raise
|
||||
end
|
||||
np := n.item
|
||||
nlast := size - 1
|
||||
pow2 := pow2_p (n.item [nlast])
|
||||
if pow2 then
|
||||
from
|
||||
np := n.item
|
||||
until
|
||||
not pow2 or np_offset >= nlast
|
||||
loop
|
||||
if np [np_offset] /= 0 then
|
||||
pow2 := False
|
||||
end
|
||||
np_offset := np_offset + 1
|
||||
end
|
||||
end
|
||||
count := leading_zeros (np [nlast])
|
||||
nbits := size * limb_bits - (count) - pow2.to_integer
|
||||
if nbits = 0 then
|
||||
target.count := 0
|
||||
else
|
||||
np := n.item
|
||||
np_offset := 0
|
||||
rp := target.item
|
||||
rp_offset := 0
|
||||
if np = rp then
|
||||
overlap := True
|
||||
create np.make_filled (0, size)
|
||||
np.copy_data (n.item, 0, 0, size)
|
||||
end
|
||||
target.resize (size)
|
||||
rp := target.item
|
||||
rp [rp_offset + size - 1] := 0
|
||||
count := 80
|
||||
from
|
||||
cmp_l := 0
|
||||
until
|
||||
cmp_l < 0 or count = 0
|
||||
loop
|
||||
state.randget (rp, rp_offset, nbits)
|
||||
cmp_l := cmp (rp, rp_offset, np, np_offset, size)
|
||||
count := count - 1
|
||||
end
|
||||
if count = 0 then
|
||||
sub_n (rp, rp_offset, rp, rp_offset, np, np_offset, size, carry)
|
||||
junk := carry.item
|
||||
end
|
||||
size := normalize (rp, rp_offset, size)
|
||||
target.count := size
|
||||
end
|
||||
end
|
||||
end
|
||||
49
contrib/ise_library/math/eapml/facilities/integer_x_sizing.e
Normal file
49
contrib/ise_library/math/eapml/facilities/integer_x_sizing.e
Normal file
@@ -0,0 +1,49 @@
|
||||
note
|
||||
description: "Summary description for {INTEGER_X_SIZING}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "My freedom is more important than your great idea. - Anonymous"
|
||||
|
||||
deferred class
|
||||
INTEGER_X_SIZING
|
||||
|
||||
inherit
|
||||
INTEGER_X_FACILITIES
|
||||
LIMB_BIT_SCANNING
|
||||
LIMB_MANIPULATION
|
||||
MP_BASES
|
||||
|
||||
feature
|
||||
|
||||
sizeinbase (op: READABLE_INTEGER_X; base: INTEGER): INTEGER_32
|
||||
-- Return the size of `op' measured in number of digits in the given base.
|
||||
-- `base' can vary from 2 to 62.
|
||||
-- The sign of `op' is ignored, just the absolute value is used.
|
||||
-- The result will be either exact or 1 too big.
|
||||
-- If `base' is a power of 2, the result is always exact.
|
||||
-- If `op' is zero the return value is always 1.
|
||||
-- This function can be used to determine the space required when converting `op' to a string.
|
||||
-- The right amount of allocation is normally two more than the value returned, one extra for
|
||||
-- a minus sign and one for the null-terminator.
|
||||
-- It will be noted that `sizeinbase(op,2)' can be used to locate the most significant 1
|
||||
-- bit in `op', counting from 1. (Unlike the bitwise functions which start from 0.
|
||||
local
|
||||
lb_base: NATURAL_32
|
||||
cnt: INTEGER_32
|
||||
totbits: INTEGER_32
|
||||
do
|
||||
if op.count.abs = 0 then
|
||||
Result := 1
|
||||
else
|
||||
cnt := leading_zeros (op.item [op.count.abs - 1])
|
||||
totbits := op.count.abs * limb_bits - cnt
|
||||
if pow2_p (base.to_natural_32) then
|
||||
lb_base := big_base (base)
|
||||
Result := (totbits + lb_base.to_integer_32 - 1) // lb_base.to_integer_32
|
||||
else
|
||||
Result := ((totbits.to_double * chars_per_bit_exactly (base)) + 1).truncated_to_integer
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
1603
contrib/ise_library/math/eapml/facilities/mp_bases.e
Normal file
1603
contrib/ise_library/math/eapml/facilities/mp_bases.e
Normal file
File diff suppressed because it is too large
Load Diff
32
contrib/ise_library/math/eapml/facilities/powers.e
Normal file
32
contrib/ise_library/math/eapml/facilities/powers.e
Normal file
@@ -0,0 +1,32 @@
|
||||
note
|
||||
description: "Summary description for {POWERS}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Giving a politician access to your wallet is like giving a dog access to your refrigerator. - Tim Barber"
|
||||
|
||||
class
|
||||
POWERS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature
|
||||
|
||||
make (digits_in_base_a: INTEGER; p_a: SPECIAL [NATURAL_32]; p_offset_a: INTEGER; n_a: INTEGER; base_a: INTEGER)
|
||||
do
|
||||
digits_in_base := digits_in_base_a
|
||||
p := p_a
|
||||
p_offset := p_offset_a
|
||||
n := n_a
|
||||
base := base_a
|
||||
end
|
||||
|
||||
feature
|
||||
|
||||
digits_in_base: INTEGER
|
||||
p: SPECIAL [NATURAL_32]
|
||||
p_offset: INTEGER
|
||||
n: INTEGER
|
||||
base: INTEGER
|
||||
end
|
||||
44
contrib/ise_library/math/eapml/facilities/rand_lc_struct.e
Normal file
44
contrib/ise_library/math/eapml/facilities/rand_lc_struct.e
Normal file
@@ -0,0 +1,44 @@
|
||||
note
|
||||
description: "Summary description for {RAND_LC_STRUCT}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Everyone wants to save the planet but no one wants to help Mom clean the dishes. - P.J. O'Rourke, in All the Trouble in the World "
|
||||
|
||||
class
|
||||
RAND_LC_STRUCT
|
||||
|
||||
inherit
|
||||
INTEGER_X_DIVISION
|
||||
LIMB_MANIPULATION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature
|
||||
|
||||
make (m2exp_a: INTEGER; a_a: READABLE_INTEGER_X; seedn: INTEGER; c: NATURAL_32)
|
||||
do
|
||||
create cp.make_filled (0, 1)
|
||||
m2exp := m2exp_a
|
||||
create seed.make_limbs (bits_to_limbs (m2exp))
|
||||
seed.count := seedn
|
||||
seed.item [0] := 1
|
||||
create a
|
||||
fdiv_r_2exp (a, a_a, m2exp)
|
||||
if a.count = 0 then
|
||||
a.count := 1
|
||||
a.item [0] := 0
|
||||
end
|
||||
cp [0] := c
|
||||
cn := (c /= 0).to_integer
|
||||
end
|
||||
|
||||
feature
|
||||
|
||||
seed: INTEGER_X
|
||||
a: INTEGER_X
|
||||
cn: INTEGER
|
||||
cp: SPECIAL [NATURAL_32]
|
||||
m2exp: INTEGER
|
||||
end
|
||||
262
contrib/ise_library/math/eapml/facilities/special_access.e
Normal file
262
contrib/ise_library/math/eapml/facilities/special_access.e
Normal file
@@ -0,0 +1,262 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_ACCESS}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "State-mandated compassion produces, not love for ones fellow man, but hatred and resentment. - Lizard"
|
||||
|
||||
deferred class
|
||||
SPECIAL_ACCESS
|
||||
|
||||
inherit
|
||||
LIMB_MANIPULATION
|
||||
MP_BASES
|
||||
SPECIAL_ARITHMETIC
|
||||
SPECIAL_DIVISION
|
||||
|
||||
feature
|
||||
|
||||
dc_get_str (target_a: STRING_8; target_offset_a: INTEGER; len_a: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; powtab: SPECIAL [POWERS]; powtab_offset: INTEGER; tmp: SPECIAL [NATURAL_32]; tmp_offset: INTEGER): INTEGER
|
||||
local
|
||||
target: STRING_8
|
||||
len: INTEGER
|
||||
pwp: SPECIAL [NATURAL_32]
|
||||
pwp_offset: INTEGER
|
||||
qp: SPECIAL [NATURAL_32]
|
||||
qp_offset: INTEGER
|
||||
rp: SPECIAL [NATURAL_32]
|
||||
rp_offset: INTEGER
|
||||
pwn: INTEGER
|
||||
qn: INTEGER
|
||||
target_offset: INTEGER
|
||||
do
|
||||
target := target_a
|
||||
len := len_a
|
||||
target_offset := target_offset_a
|
||||
if op1_count < 15 then
|
||||
if op1_count /= 0 then
|
||||
target_offset := sb_get_str (target, target_offset, len, op1, op1_offset, op1_count, powtab, powtab_offset)
|
||||
else
|
||||
from
|
||||
until
|
||||
len /= 0
|
||||
loop
|
||||
target [target_offset] := '%U'
|
||||
target_offset := target_offset + 1
|
||||
len := len - 1
|
||||
end
|
||||
end
|
||||
else
|
||||
pwp := powtab [powtab_offset].p
|
||||
pwn := powtab [powtab_offset].n
|
||||
if op1_count < pwn or (op1_count = pwn and cmp (op1, op1_offset, pwp, pwp_offset, op1_count) < 0) then
|
||||
target_offset := dc_get_str (target, target_offset, len, op1, op1_offset, op1_count, powtab, powtab_offset - 1, tmp, tmp_offset)
|
||||
else
|
||||
qp := tmp
|
||||
qp_offset := tmp_offset
|
||||
rp := op1
|
||||
rp_offset := op1_offset
|
||||
tdiv_qr (qp, qp_offset, rp, rp_offset, op1, op1_offset, op1_count, pwp, pwp_offset, pwn)
|
||||
qn := op1_count - pwn
|
||||
qn := qn + (qp [qp_offset + qn] /= 0).to_integer
|
||||
if len /= 0 then
|
||||
len := len - powtab [powtab_offset].digits_in_base
|
||||
end
|
||||
target_offset := dc_get_str (target, target_offset, len, qp, qp_offset, qn, powtab, powtab_offset - 1, tmp, tmp_offset + op1_count - pwn + 1)
|
||||
target_offset := dc_get_str (target, target_offset, powtab [powtab_offset].digits_in_base, rp, rp_offset, pwn, powtab, powtab_offset - 1, tmp, tmp_offset)
|
||||
end
|
||||
end
|
||||
Result := target_offset
|
||||
end
|
||||
|
||||
get_str (target: STRING_8; target_offset: INTEGER; base: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER): INTEGER
|
||||
local
|
||||
powtab_mem_ptr: SPECIAL [NATURAL_32]
|
||||
powtab_mem_ptr_offset: INTEGER
|
||||
big_base_l: NATURAL_32
|
||||
digits_in_base: INTEGER
|
||||
powtab: SPECIAL [POWERS]
|
||||
pi: INTEGER
|
||||
n: INTEGER
|
||||
t: INTEGER
|
||||
p: SPECIAL [NATURAL_32]
|
||||
p_offset: INTEGER
|
||||
n1: NATURAL_32
|
||||
n0: NATURAL_32
|
||||
bits_per_digit: INTEGER
|
||||
count: INTEGER
|
||||
bit_pos: INTEGER
|
||||
i: INTEGER
|
||||
s: INTEGER
|
||||
bits: INTEGER
|
||||
do
|
||||
if op1_count = 0 then
|
||||
target [target_offset] := '%U'
|
||||
Result := 1
|
||||
else
|
||||
if pow2_p (base.to_natural_32) then
|
||||
bits_per_digit := big_base (base).to_integer_32
|
||||
s := target_offset
|
||||
n1 := op1 [op1_offset + op1_count - 1]
|
||||
count := leading_zeros (n1)
|
||||
bits := limb_bits * op1_count - count
|
||||
count := bits \\ bits_per_digit
|
||||
if count /= 0 then
|
||||
bits := bits + bits_per_digit - count
|
||||
end
|
||||
bit_pos := bits - (op1_count - 1) * limb_bits
|
||||
from
|
||||
i := op1_count - 1
|
||||
until
|
||||
i < 0
|
||||
loop
|
||||
bit_pos := bit_pos - bits_per_digit
|
||||
from
|
||||
until
|
||||
bit_pos < 0
|
||||
loop
|
||||
target [s] := ((n1 |>> bit_pos).bit_and (((1).to_natural_32 |<< bits_per_digit) - 1)).to_character_8
|
||||
s := s + 1
|
||||
bit_pos := bit_pos - bits_per_digit
|
||||
end
|
||||
i := i - 1
|
||||
if i >= 0 then
|
||||
n0 := (n1 |<< -bit_pos).bit_and (((1).to_natural_32 |<< bits_per_digit) - 1)
|
||||
n1 := op1 [op1_offset + i]
|
||||
bit_pos := bit_pos + limb_bits
|
||||
target [s] := (n0.bit_or (n1 |>> bit_pos)).to_character_8
|
||||
s := s + 1
|
||||
end
|
||||
end
|
||||
Result := s - target_offset
|
||||
else
|
||||
if op1_count < 30 then
|
||||
create powtab.make_empty (1)
|
||||
create p.make_empty (0)
|
||||
powtab.extend (create {POWERS}.make (0, p, 0, 0, base))
|
||||
Result := sb_get_str (target, target_offset, 0, op1, op1_offset, op1_count, powtab, 0)
|
||||
else
|
||||
create powtab_mem_ptr.make_filled (0, 2 * op1_count + 30)
|
||||
big_base_l := big_base (base)
|
||||
digits_in_base := chars_per_limb (base)
|
||||
create powtab.make_empty (30)
|
||||
create p.make_filled (0, 0)
|
||||
powtab.extend (create {POWERS}.make (0, p, 0, 0, base))
|
||||
create p.make_filled (big_base_l, 1)
|
||||
powtab.extend (create {POWERS}.make (digits_in_base, p, 0, 1, base))
|
||||
create p.make_filled (big_base_l, 1)
|
||||
powtab.extend (create {POWERS}.make (digits_in_base, p, 0, 1, base))
|
||||
n := 1
|
||||
pi := 2
|
||||
create p.make_filled (big_base_l, 1)
|
||||
p_offset := 0
|
||||
from
|
||||
until
|
||||
2 * n > op1_count
|
||||
loop
|
||||
pi := pi + 1
|
||||
t := powtab_mem_ptr_offset
|
||||
powtab_mem_ptr_offset := powtab_mem_ptr_offset + 2 * n
|
||||
sqr_n (powtab_mem_ptr, t, p, p_offset, n)
|
||||
n := n * 2
|
||||
n := n - (powtab_mem_ptr [t + n - 1] = 0).to_integer
|
||||
digits_in_base := digits_in_base * 2
|
||||
powtab_mem_ptr_offset := t
|
||||
powtab.extend (create {POWERS}.make (digits_in_base, p, 0, n, base))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sb_get_str (target: STRING_8; target_offset_a: INTEGER; len_a: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count_a: INTEGER; powtab: SPECIAL [POWERS]; powtab_offset: INTEGER): INTEGER
|
||||
local
|
||||
rl: CELL [NATURAL_32]
|
||||
ul: CELL [NATURAL_32]
|
||||
s: INTEGER
|
||||
base: INTEGER
|
||||
l: INTEGER
|
||||
buf: SPECIAL [NATURAL_8]
|
||||
buf_offset: INTEGER
|
||||
rp: SPECIAL [NATURAL_32]
|
||||
rp_offset: INTEGER
|
||||
buff_alloc: INTEGER
|
||||
op1_count: INTEGER
|
||||
i: INTEGER
|
||||
frac: CELL [NATURAL_32]
|
||||
digit: CELL [NATURAL_32]
|
||||
junk: NATURAL_32
|
||||
chars_per_limb_l: INTEGER
|
||||
big_base_l: NATURAL_32
|
||||
big_base_inverted_l: NATURAL_32
|
||||
normalization_steps: INTEGER
|
||||
target_offset: INTEGER
|
||||
len: INTEGER
|
||||
do
|
||||
create digit.put (0)
|
||||
create frac.put (0)
|
||||
create ul.put (0)
|
||||
create rl.put (0)
|
||||
len := len_a
|
||||
target_offset := target_offset_a
|
||||
op1_count := op1_count_a
|
||||
buff_alloc := 30 * 8 * 4 * 7 // 11
|
||||
create buf.make_filled (0, buff_alloc)
|
||||
create rp.make_filled (0, 30)
|
||||
base := powtab [powtab_offset].base
|
||||
chars_per_limb_l := chars_per_limb (base)
|
||||
big_base_l := big_base (base)
|
||||
big_base_inverted_l := big_base_inverted (base)
|
||||
normalization_steps := leading_zeros (big_base_l)
|
||||
rp.copy_data (op1, op1_offset, rp_offset + 1, op1_count)
|
||||
s := buf_offset + buff_alloc
|
||||
from
|
||||
until
|
||||
op1_count <= 1
|
||||
loop
|
||||
junk := preinv_divrem_1 (rp, rp_offset, 1, rp, rp_offset + 1, op1_count, big_base_l, big_base_inverted_l, normalization_steps)
|
||||
op1_count := op1_count - (rp [rp_offset + op1_count] = 0).to_integer
|
||||
frac.put (rp [rp_offset] + 1)
|
||||
s := s - chars_per_limb_l
|
||||
i := chars_per_limb_l
|
||||
from
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
umul_ppmm (digit, frac, frac.item, base.to_natural_32)
|
||||
buf [s] := digit.item.to_natural_8
|
||||
s := s + 1
|
||||
i := i - 1
|
||||
end
|
||||
s := s - chars_per_limb_l
|
||||
end
|
||||
ul.put (rp [rp_offset + 1])
|
||||
from
|
||||
until
|
||||
ul.item = 0
|
||||
loop
|
||||
udiv_qrnd_unnorm (ul, rl, ul.item, base.to_natural_32)
|
||||
s := s - 1
|
||||
buf [s] := rl.item.to_natural_8
|
||||
end
|
||||
l := buf_offset + buff_alloc - s
|
||||
from
|
||||
until
|
||||
l >= len
|
||||
loop
|
||||
target [target_offset] := '%U'
|
||||
target_offset := target_offset + 1
|
||||
len := len - 1
|
||||
end
|
||||
from
|
||||
until
|
||||
l = 0
|
||||
loop
|
||||
target [target_offset] := buf [s].to_character_8
|
||||
s := s + 1
|
||||
target_offset := target_offset + 1
|
||||
l := l - 1
|
||||
end
|
||||
Result := target_offset - target_offset_a
|
||||
end
|
||||
end
|
||||
1022
contrib/ise_library/math/eapml/facilities/special_arithmetic.e
Normal file
1022
contrib/ise_library/math/eapml/facilities/special_arithmetic.e
Normal file
File diff suppressed because it is too large
Load Diff
159
contrib/ise_library/math/eapml/facilities/special_assignment.e
Normal file
159
contrib/ise_library/math/eapml/facilities/special_assignment.e
Normal file
@@ -0,0 +1,159 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_ASSIGNMENT}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Concentrated political power is the most dangerous thing on earth. - Rudolph Rummel"
|
||||
|
||||
deferred class
|
||||
SPECIAL_ASSIGNMENT
|
||||
|
||||
inherit
|
||||
MP_BASES
|
||||
LIMB_MANIPULATION
|
||||
SPECIAL_ARITHMETIC
|
||||
|
||||
feature
|
||||
|
||||
set_str (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; str: SPECIAL [NATURAL_8]; str_offset_a: INTEGER; str_len: INTEGER; base: INTEGER): INTEGER
|
||||
require
|
||||
base >= 2
|
||||
-- str_len >= 1
|
||||
local
|
||||
str_offset: INTEGER
|
||||
size: INTEGER
|
||||
big_base_l: NATURAL_32
|
||||
chars_per_limb_l: INTEGER
|
||||
res_digit: NATURAL_32
|
||||
s: INTEGER
|
||||
next_bitpos: INTEGER
|
||||
bits_per_indigit: INTEGER
|
||||
inp_digit: NATURAL_8
|
||||
i: INTEGER
|
||||
j: INTEGER
|
||||
cy_limb: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
str_offset := str_offset_a
|
||||
big_base_l := big_base (base)
|
||||
chars_per_limb_l := chars_per_limb (base)
|
||||
size := 0
|
||||
if pow2_p (base.to_natural_32) then
|
||||
bits_per_indigit := big_base_l.to_integer_32
|
||||
res_digit := 0
|
||||
next_bitpos := 0
|
||||
from
|
||||
s := str_offset + str_len - 1
|
||||
until
|
||||
s < str_offset
|
||||
loop
|
||||
inp_digit := str [s]
|
||||
res_digit := res_digit.bit_or (inp_digit.to_natural_32 |<< next_bitpos)
|
||||
next_bitpos := next_bitpos + bits_per_indigit
|
||||
if next_bitpos >= limb_bits then
|
||||
target [target_offset + size] := res_digit
|
||||
size := size + 1
|
||||
next_bitpos := next_bitpos - limb_bits
|
||||
res_digit := inp_digit |>> (bits_per_indigit - next_bitpos)
|
||||
end
|
||||
s := s - 1
|
||||
end
|
||||
if res_digit /= 0 then
|
||||
target [target_offset + size] := res_digit
|
||||
size := size + 1
|
||||
end
|
||||
Result := size
|
||||
else
|
||||
if str_len < str_len.max_value then
|
||||
from
|
||||
i := chars_per_limb_l
|
||||
until
|
||||
i >= str_len
|
||||
loop
|
||||
res_digit := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
if base = 10 then
|
||||
from
|
||||
j := 9 - 1
|
||||
until
|
||||
j = 0
|
||||
loop
|
||||
res_digit := res_digit * 10 + str [str_offset].to_natural_32
|
||||
str_offset := str_offset + 1
|
||||
j := j - 1
|
||||
end
|
||||
else
|
||||
from
|
||||
j := chars_per_limb_l - 1
|
||||
until
|
||||
j = 0
|
||||
loop
|
||||
res_digit := res_digit * base.to_natural_32 + str [str_offset].to_natural_32
|
||||
str_offset := str_offset + 1
|
||||
j := j - 1
|
||||
end
|
||||
end
|
||||
if size = 0 then
|
||||
if res_digit /= 0 then
|
||||
target [target_offset] := res_digit
|
||||
size := 1
|
||||
end
|
||||
else
|
||||
mul_1 (target, target_offset, target, target_offset, size, big_base_l, carry)
|
||||
cy_limb := carry.item
|
||||
add_1 (target, target_offset, target, target_offset, size, res_digit, carry)
|
||||
cy_limb := cy_limb + carry.item
|
||||
if cy_limb /= 0 then
|
||||
target [target_offset + size] := cy_limb
|
||||
size := size + 1
|
||||
end
|
||||
end
|
||||
i := i + chars_per_limb_l
|
||||
end
|
||||
big_base_l := base.to_natural_32
|
||||
res_digit := str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
if base = 10 then
|
||||
from
|
||||
j := str_len - (i - 9) - 1
|
||||
until
|
||||
j <= 0
|
||||
loop
|
||||
res_digit := res_digit * 10 + str [str_offset]
|
||||
str_offset := str_offset + 1
|
||||
big_base_l := big_base_l * 10
|
||||
j := j - 1
|
||||
end
|
||||
else
|
||||
from
|
||||
j := str_len - (i - chars_per_limb_l) - 1
|
||||
until
|
||||
j <= 0
|
||||
loop
|
||||
res_digit := res_digit * base.to_natural_32 + str [str_offset].to_natural_32
|
||||
str_offset := str_offset + 1
|
||||
big_base_l := big_base_l * base.to_natural_32
|
||||
j := j - 1
|
||||
end
|
||||
end
|
||||
if size = 0 then
|
||||
if res_digit /= 0 then
|
||||
target [target_offset] := res_digit
|
||||
size := 1
|
||||
end
|
||||
else
|
||||
mul_1 (target, target_offset, target, target_offset, size, big_base_l, carry)
|
||||
cy_limb := carry.item
|
||||
add_1 (target, target_offset, target, target_offset, size, res_digit, carry)
|
||||
cy_limb := cy_limb + carry.item
|
||||
if cy_limb /= 0 then
|
||||
target [target_offset + size] := cy_limb
|
||||
size := size + 1
|
||||
end
|
||||
end
|
||||
Result := size
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_COMPARISON}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "No nation was ever ruined by trade. - Benjamin Franklin"
|
||||
|
||||
deferred class
|
||||
SPECIAL_COMPARISON
|
||||
|
||||
feature
|
||||
|
||||
cmp (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER; size: INTEGER): INTEGER
|
||||
local
|
||||
i: INTEGER
|
||||
x: NATURAL_32
|
||||
y: NATURAL_32
|
||||
do
|
||||
Result := 0
|
||||
from
|
||||
i := size - 1
|
||||
until
|
||||
i < 0 or Result /= 0
|
||||
loop
|
||||
x := op1 [op1_offset + i]
|
||||
y := op2 [op2_offset + i]
|
||||
if x /= y then
|
||||
if x > y then
|
||||
Result := 1
|
||||
else
|
||||
Result := -1
|
||||
end
|
||||
end
|
||||
i := i - 1
|
||||
variant
|
||||
i + 2
|
||||
end
|
||||
end
|
||||
end
|
||||
1102
contrib/ise_library/math/eapml/facilities/special_division.e
Normal file
1102
contrib/ise_library/math/eapml/facilities/special_division.e
Normal file
File diff suppressed because it is too large
Load Diff
1103
contrib/ise_library/math/eapml/facilities/special_gcd.e
Normal file
1103
contrib/ise_library/math/eapml/facilities/special_gcd.e
Normal file
File diff suppressed because it is too large
Load Diff
332
contrib/ise_library/math/eapml/facilities/special_logic.e
Normal file
332
contrib/ise_library/math/eapml/facilities/special_logic.e
Normal file
@@ -0,0 +1,332 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_LOGIC}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "It is a free market that makes monopolies impossible. - Ayn Rand"
|
||||
|
||||
deferred class
|
||||
SPECIAL_LOGIC
|
||||
|
||||
inherit
|
||||
LIMB_MANIPULATION
|
||||
|
||||
feature
|
||||
|
||||
com_n (target: SPECIAL [NATURAL_32]; target_offset_a: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER; op1_count_a: INTEGER)
|
||||
require
|
||||
op1_count_a >= 1
|
||||
local
|
||||
target_offset: INTEGER
|
||||
op1_offset: INTEGER
|
||||
op1_count: INTEGER
|
||||
do
|
||||
target_offset := target_offset_a
|
||||
op1_offset := op1_offset_a
|
||||
op1_count := op1_count_a
|
||||
from
|
||||
until
|
||||
op1_count = 0
|
||||
loop
|
||||
target [target_offset] := op1 [op1_offset].bit_not
|
||||
target_offset := target_offset + 1
|
||||
op1_offset := op1_offset + 1
|
||||
op1_count := op1_count - 1
|
||||
end
|
||||
end
|
||||
|
||||
hamdist (op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset_a: INTEGER; n_a: INTEGER): INTEGER
|
||||
local
|
||||
p0: NATURAL_32
|
||||
p1: NATURAL_32
|
||||
p2: NATURAL_32
|
||||
p3: NATURAL_32
|
||||
x: NATURAL_32
|
||||
p01: NATURAL_32
|
||||
p23: NATURAL_32
|
||||
i: INTEGER
|
||||
op1_offset: INTEGER
|
||||
n: INTEGER
|
||||
op2_offset: INTEGER
|
||||
do
|
||||
op2_offset := op2_offset_a
|
||||
n := n_a
|
||||
op1_offset := op1_offset_a
|
||||
from
|
||||
i := n |>> 2
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
p0 := op1 [op1_offset].bit_xor (op2 [op2_offset])
|
||||
p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3)
|
||||
p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5)
|
||||
|
||||
p1 := op1 [op1_offset + 1].bit_xor (op2 [op2_offset + 1])
|
||||
p1 := p1 - (p1 |>> 1).bit_and (limb_max // 3)
|
||||
p1 := (p1 |>> 2).bit_and (limb_max // 5) + p1.bit_and (limb_max // 5)
|
||||
|
||||
p01 := p0 + p1
|
||||
p01 := (p01 |>> 4).bit_and (limb_max // 17) + p01.bit_and (limb_max // 17)
|
||||
|
||||
p2 := op1 [op1_offset + 2].bit_xor (op2 [op2_offset + 2])
|
||||
p2 := p2 - (p2 |>> 1).bit_and (limb_max // 3)
|
||||
p2 := (p2 |>> 2).bit_and (limb_max // 5) + p2.bit_and (limb_max // 5)
|
||||
|
||||
p3 := op1 [op1_offset + 3].bit_xor (op2 [op2_offset + 3])
|
||||
p3 := p3 - (p3 |>> 1).bit_and (limb_max // 3)
|
||||
p3 := (p3 |>> 2).bit_and (limb_max // 5) + p3.bit_and (limb_max // 5)
|
||||
|
||||
p23 := p2 + p3
|
||||
p23 := (p23 |>> 4).bit_and (limb_max // 17) + p23.bit_and (limb_max // 17)
|
||||
|
||||
x := p01 + p23
|
||||
x := (x |>> 8) + x
|
||||
x := (x |>> 16) + x
|
||||
Result := Result + x.bit_and (0xff).to_integer_32
|
||||
op1_offset := op1_offset + 4
|
||||
op2_offset := op2_offset + 4
|
||||
i := i - 1
|
||||
end
|
||||
n := n.bit_and (3)
|
||||
if n /= 0 then
|
||||
x := 0
|
||||
from
|
||||
until
|
||||
n = 0
|
||||
loop
|
||||
p0 := op1 [op1_offset].bit_xor (op2 [op2_offset])
|
||||
p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3)
|
||||
p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5)
|
||||
p0 := ((p0 |>> 4) | p0).bit_and (limb_max // 17)
|
||||
x := x + p0
|
||||
op1_offset := op1_offset + 1
|
||||
op2_offset := op2_offset + 1
|
||||
n := n - 1
|
||||
end
|
||||
x := (x |>> 8) + x
|
||||
x := (x |>> 16) + x
|
||||
Result := Result + x.bit_and (0xff).to_integer_32
|
||||
end
|
||||
end
|
||||
|
||||
lshift (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; count: INTEGER_32; carry: CELL [NATURAL_32])
|
||||
require
|
||||
target.valid_index (target_offset)
|
||||
target.valid_index (target_offset + n - 1)
|
||||
op1.valid_index (op1_offset)
|
||||
op1.valid_index (op1_offset + n - 1)
|
||||
count > 0
|
||||
count < 32
|
||||
local
|
||||
high_limb: NATURAL_32
|
||||
low_limb: NATURAL_32
|
||||
tnc: INTEGER_32
|
||||
i: INTEGER_32
|
||||
up: INTEGER_32
|
||||
rp: INTEGER_32
|
||||
do
|
||||
up := op1_offset + n
|
||||
rp := target_offset + n
|
||||
tnc := 32 - count
|
||||
up := up - 1
|
||||
low_limb := op1 [up]
|
||||
carry.put (low_limb |>> tnc)
|
||||
high_limb := low_limb |<< count
|
||||
from
|
||||
i := n - 1
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
up := up - 1
|
||||
low_limb := op1 [up]
|
||||
rp := rp - 1
|
||||
target [rp] := high_limb.bit_or (low_limb |>> tnc)
|
||||
high_limb := low_limb |<< count
|
||||
i := i - 1
|
||||
end
|
||||
rp := rp - 1
|
||||
target [rp] := high_limb
|
||||
end
|
||||
|
||||
rshift (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; count: INTEGER_32; carry: CELL [NATURAL_32])
|
||||
local
|
||||
high_limb: NATURAL_32
|
||||
low_limb: NATURAL_32
|
||||
tnc: INTEGER_32
|
||||
i: INTEGER_32
|
||||
op1_cursor: INTEGER_32
|
||||
target_cursor: INTEGER_32
|
||||
do
|
||||
tnc := 32 - count
|
||||
op1_cursor := op1_offset
|
||||
high_limb := op1 [op1_cursor]
|
||||
op1_cursor := op1_cursor + 1
|
||||
carry.put (high_limb |<< tnc)
|
||||
low_limb := high_limb |>> count
|
||||
from
|
||||
i := n - 1
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
high_limb := op1 [op1_cursor]
|
||||
op1_cursor := op1_cursor + 1
|
||||
target [target_cursor] := low_limb.bit_or (high_limb |<< tnc)
|
||||
target_cursor := target_cursor + 1
|
||||
low_limb := high_limb |>> count
|
||||
i := i - 1
|
||||
end
|
||||
target [target_cursor] := low_limb
|
||||
end
|
||||
|
||||
popcount (op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER; n_a: INTEGER): INTEGER
|
||||
local
|
||||
p0: NATURAL_32
|
||||
p1: NATURAL_32
|
||||
p2: NATURAL_32
|
||||
p3: NATURAL_32
|
||||
x: NATURAL_32
|
||||
p01: NATURAL_32
|
||||
p23: NATURAL_32
|
||||
i: INTEGER
|
||||
op1_offset: INTEGER
|
||||
n: INTEGER
|
||||
do
|
||||
n := n_a
|
||||
op1_offset := op1_offset_a
|
||||
from
|
||||
i := n |>> 2
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
p0 := op1 [op1_offset]
|
||||
p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3)
|
||||
p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5)
|
||||
|
||||
p1 := op1 [op1_offset + 1]
|
||||
p1 := p1 - (p1 |>> 1).bit_and (limb_max // 3)
|
||||
p1 := (p1 |>> 2).bit_and (limb_max // 5) + p1.bit_and (limb_max // 5)
|
||||
|
||||
p01 := p0 + p1
|
||||
p01 := (p01 |>> 4).bit_and (limb_max // 17) + p01.bit_and (limb_max // 17)
|
||||
|
||||
p2 := op1 [op1_offset + 2]
|
||||
p2 := p2 - (p2 |>> 1).bit_and (limb_max // 3)
|
||||
p2 := (p2 |>> 2).bit_and (limb_max // 5) + p2.bit_and (limb_max // 5)
|
||||
|
||||
p3 := op1 [op1_offset + 3]
|
||||
p3 := p3 - (p3 |>> 1).bit_and (limb_max // 3)
|
||||
p3 := (p3 |>> 2).bit_and (limb_max // 5) + p3.bit_and (limb_max // 5)
|
||||
|
||||
p23 := p2 + p3
|
||||
p23 := (p23 |>> 4).bit_and (limb_max // 17) + p23.bit_and (limb_max // 17)
|
||||
|
||||
x := p01 + p23
|
||||
x := (x |>> 8) + x
|
||||
x := (x |>> 16) + x
|
||||
Result := Result + x.bit_and (0xff).to_integer_32
|
||||
op1_offset := op1_offset + 4
|
||||
i := i - 1
|
||||
end
|
||||
n := n.bit_and (3)
|
||||
if n /= 0 then
|
||||
x := 0
|
||||
from
|
||||
until
|
||||
n = 0
|
||||
loop
|
||||
p0 := op1 [op1_offset]
|
||||
p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3)
|
||||
p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5)
|
||||
p0 := ((p0 |>> 4) | p0).bit_and (limb_max // 17)
|
||||
x := x + p0
|
||||
op1_offset := op1_offset + 1
|
||||
n := n - 1
|
||||
end
|
||||
x := (x |>> 8) + x
|
||||
x := (x |>> 16) + x
|
||||
Result := Result + x.bit_and (0xff).to_integer_32
|
||||
end
|
||||
end
|
||||
|
||||
bit_xor_lshift (target: SPECIAL [NATURAL_32] target_offset: INTEGER op1: SPECIAL [NATURAL_32] op1_offset: INTEGER op1_count: INTEGER op2: SPECIAL [NATURAL_32] op2_offset: INTEGER op2_count: INTEGER op2_lshift: INTEGER)
|
||||
require
|
||||
op2_lshift >= 0
|
||||
op1 /= op2
|
||||
target /= op2
|
||||
op1_count = 0 or op1.valid_index (op1_offset)
|
||||
op1_count = 0 or op1.valid_index (op1_offset + op1_count - 1)
|
||||
op2_count = 0 or op2.valid_index (op2_offset)
|
||||
op2_count = 0 or op2.valid_index (op2_offset + op2_count - 1)
|
||||
(op1_count = 0 and op2_count = 0) or target.valid_index (target_offset)
|
||||
(op1_count = 0 and op2_count = 0) or target.valid_index (target_offset + op1_count.max (op2_count + bits_to_limbs (op2_lshift)) - 1)
|
||||
local
|
||||
op2_limb_high: NATURAL_32
|
||||
op2_limb_low: NATURAL_32
|
||||
op2_limb: NATURAL_32
|
||||
cursor: INTEGER
|
||||
shift_limbs: INTEGER
|
||||
shift_bits: INTEGER
|
||||
do
|
||||
shift_limbs := op2_lshift // limb_bits
|
||||
shift_bits := op2_lshift \\ limb_bits
|
||||
target.copy_data (op1, op1_offset, target_offset, shift_limbs)
|
||||
from
|
||||
until
|
||||
cursor >= op2_count or cursor >= op1_count - shift_limbs
|
||||
loop
|
||||
op2_limb_low := op2_limb_high
|
||||
op2_limb_high := op2 [op2_offset + cursor]
|
||||
op2_limb := extract_limb (shift_bits, op2_limb_high, op2_limb_low)
|
||||
target [target_offset + shift_limbs + cursor] := op2_limb.bit_xor (op1 [op1_offset + shift_limbs + cursor])
|
||||
cursor := cursor + 1
|
||||
end
|
||||
if cursor >= op2_count then
|
||||
op2_limb_low := op2_limb_high
|
||||
op2_limb := extract_limb (shift_bits, 0, op2_limb_low)
|
||||
if cursor >= op1_count - shift_limbs then
|
||||
target [target_offset + shift_limbs + cursor] := op2_limb
|
||||
else
|
||||
target [target_offset + shift_limbs + cursor] := op2_limb.bit_xor (op1 [op1_offset + shift_limbs + cursor])
|
||||
cursor := cursor + 1
|
||||
target.copy_data (op1, op1_offset + shift_limbs + cursor, target_offset + shift_limbs + cursor, op1_count - cursor - shift_limbs)
|
||||
end
|
||||
else
|
||||
from
|
||||
until
|
||||
cursor >= op2_count
|
||||
loop
|
||||
op2_limb_low := op2_limb_high
|
||||
op2_limb_high := op2 [op2_offset + cursor]
|
||||
op2_limb := extract_limb (shift_bits, op2_limb_high, op2_limb_low)
|
||||
target [target_offset + shift_limbs + cursor] := op2_limb
|
||||
cursor := cursor + 1
|
||||
end
|
||||
op2_limb_low := op2_limb_high
|
||||
op2_limb := extract_limb (shift_bits, 0, op2_limb_low)
|
||||
target [target_offset + shift_limbs + cursor] := op2_limb
|
||||
end
|
||||
end
|
||||
|
||||
bit_xor (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER; op2_count: INTEGER)
|
||||
require
|
||||
(op1_count = 0 and op2_count = 0) or target.valid_index (target_offset)
|
||||
(op1_count = 0 and op2_count = 0) or target.valid_index (target_offset + op1_count.max (op2_count) - 1)
|
||||
local
|
||||
cursor: INTEGER
|
||||
min: INTEGER
|
||||
do
|
||||
from
|
||||
min := op1_count.min (op2_count)
|
||||
until
|
||||
cursor >= min
|
||||
loop
|
||||
target [target_offset + cursor] := op1 [op1_offset + cursor].bit_xor (op2 [op2_offset + cursor])
|
||||
cursor := cursor + 1
|
||||
end
|
||||
if op1_count > op2_count then
|
||||
target.copy_data (op1, op1_offset + cursor, target_offset + cursor, op1_count - cursor)
|
||||
elseif op2_count > op1_count then
|
||||
target.copy_data (op2, op2_offset + cursor, target_offset + cursor, op2_count - cursor)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,849 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_NUMBER_THEORETIC}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "The best argument against democracy is a five-minute conversation with the average voter. - Winston Churchill"
|
||||
|
||||
deferred class
|
||||
SPECIAL_NUMBER_THEORETIC
|
||||
|
||||
inherit
|
||||
SPECIAL_DIVISION
|
||||
SPECIAL_UTILITY
|
||||
SPECIAL_LOGIC
|
||||
LIMB_MANIPULATION
|
||||
|
||||
feature
|
||||
|
||||
gcdext_div2 (n1_a: NATURAL_32; n0_a: NATURAL_32; d1_a: NATURAL_32; d0_a: NATURAL_32): NATURAL_32
|
||||
require
|
||||
d1_a /= 0 or d0_a /= 0
|
||||
local
|
||||
q: NATURAL_32
|
||||
count: INTEGER
|
||||
d1: NATURAL_32
|
||||
d0: NATURAL_32
|
||||
n1: CELL [NATURAL_32]
|
||||
n0: CELL [NATURAL_32]
|
||||
do
|
||||
create n1.put (n1_a)
|
||||
create n0.put (n0_a)
|
||||
d1 := d1_a
|
||||
d0 := d0_a
|
||||
if n1.item.bit_test (limb_high_bit) then
|
||||
from
|
||||
count := 1
|
||||
invariant
|
||||
d1 /= 0 or d0 /= 0
|
||||
until
|
||||
d1.bit_test (limb_high_bit)
|
||||
loop
|
||||
d1 := (d1 |<< 1).bit_or (d0 |>> (limb_bits - 1))
|
||||
d0 := d0 |<< 1
|
||||
count := count + 1
|
||||
end
|
||||
q := 0
|
||||
from
|
||||
until
|
||||
count = 0
|
||||
loop
|
||||
q := q |<< 1
|
||||
if n1.item > d1 or (n1.item = d1 and n0.item >= d0) then
|
||||
sub_ddmmss (n1, n0, n1.item, n0.item, d1, d0)
|
||||
q := q.bit_or (1)
|
||||
end
|
||||
d0 := (d1 |<< (limb_bits - 1)).bit_or (d0 |>> 1)
|
||||
d1 := d1 |>> 1
|
||||
count := count - 1
|
||||
end
|
||||
Result := q
|
||||
else
|
||||
from
|
||||
count := 0
|
||||
until
|
||||
n1.item <= d1 and (n1.item /= d1 or n0.item < d0)
|
||||
loop
|
||||
d1 := (d1 |<< 1).bit_or (d0 |>> (limb_bits - 1))
|
||||
d0 := d0 |<< 1
|
||||
count := count + 1
|
||||
end
|
||||
q := 0
|
||||
from
|
||||
until
|
||||
count = 0
|
||||
loop
|
||||
d0 := (d1 |<< (limb_bits - 1)).bit_or (d0 |>> 1)
|
||||
d1 := d1 |>> 1
|
||||
q := q |<< 1
|
||||
if n1.item > d1 or (n1.item = d1 and n0.item >= d0) then
|
||||
sub_ddmmss (n1, n0, n1.item, n0.item, d1, d0)
|
||||
q := q.bit_or (1)
|
||||
end
|
||||
count := count - 1
|
||||
end
|
||||
Result := q
|
||||
end
|
||||
end
|
||||
|
||||
basic_gcdext (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; cofactor: SPECIAL [NATURAL_32]; cofactor_offset: INTEGER_32; cofactor_count: TUPLE [cofactor_count: INTEGER_32]; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; op2_count: INTEGER_32): INTEGER
|
||||
require
|
||||
op1_count >= op2_count
|
||||
target.valid_index (target_offset)
|
||||
target.valid_index (target_offset + op1_count - 1)
|
||||
cofactor.valid_index (cofactor_offset)
|
||||
cofactor.valid_index (cofactor_offset + op1_count - 1)
|
||||
op1.valid_index (op1_offset)
|
||||
op1.valid_index (op1_offset + op1_count - 0)
|
||||
op1 [op1_offset + op1_count - 1] /= 0
|
||||
op2.valid_index (op2_offset)
|
||||
op2.valid_index (op2_offset + op2_count - 0)
|
||||
op2 [op2_offset + op2_count - 1] /= 0
|
||||
op2_count >= 1
|
||||
local
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER_32
|
||||
s1p: SPECIAL [NATURAL_32]
|
||||
s1p_offset: INTEGER
|
||||
do
|
||||
create tp.make_filled (0, op1_count + 1)
|
||||
tp_offset := 0
|
||||
create s1p.make_filled (0, op1_count + 1)
|
||||
s1p_offset := 0
|
||||
cofactor.fill_with (0, cofactor_offset, cofactor_offset + op1_count - 1)
|
||||
s1p.fill_with (0, s1p_offset, s1p_offset + op1_count - 1)
|
||||
cofactor [cofactor_offset] := 1
|
||||
s1p [s1p_offset] := 0
|
||||
if op1_count > op2_count then
|
||||
tdiv_qr (tp, tp_offset, op1, op1_offset, op1, op1_offset, op1_count, op2, op2_offset, op2_count)
|
||||
cofactor [cofactor_offset] := 0
|
||||
s1p [s1p_offset] := 1
|
||||
Result := basic_gcdext_arranged (target, target_offset, cofactor, cofactor_offset, cofactor_count, op2, op2_offset, op2_count, op1, op1_offset, op1_count, -1, s1p, s1p_offset, tp, tp_offset)
|
||||
else
|
||||
Result := basic_gcdext_arranged (target, target_offset, cofactor, cofactor_offset, cofactor_count, op1, op1_offset, op1_count, op2, op2_offset, op2_count, 1, s1p, s1p_offset, tp, tp_offset)
|
||||
end
|
||||
end
|
||||
|
||||
basic_gcdext_arranged (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; cofactor_a: SPECIAL [NATURAL_32]; cofactor_offset_a: INTEGER_32; cofactor_count: TUPLE [cofactor_count: INTEGER_32]; op1_a: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER_32; op1_count_a: INTEGER_32; op2_a: SPECIAL [NATURAL_32]; op2_offset_a: INTEGER_32; op2_count_a: INTEGER_32; sign_a: INTEGER; s1p_a: SPECIAL [NATURAL_32]; s1p_offset_a: INTEGER; tp_a: SPECIAL [NATURAL_32]; tp_offset_a: INTEGER): INTEGER
|
||||
local
|
||||
a: NATURAL_32
|
||||
b: NATURAL_32
|
||||
c: NATURAL_32
|
||||
d: NATURAL_32
|
||||
wp: SPECIAL [NATURAL_32]
|
||||
wp_offset: INTEGER_32
|
||||
orig_s0p: SPECIAL [NATURAL_32]
|
||||
orig_s0p_offset: INTEGER
|
||||
use_double_flag: BOOLEAN
|
||||
cnt: INTEGER_32
|
||||
assign_l: NATURAL_32
|
||||
op2_count: INTEGER
|
||||
done: BOOLEAN
|
||||
done_2: BOOLEAN
|
||||
uh: NATURAL_32
|
||||
vh: NATURAL_32
|
||||
ul: NATURAL_32
|
||||
vl: NATURAL_32
|
||||
tac: NATURAL_32
|
||||
tbd: NATURAL_32
|
||||
q1: NATURAL_32
|
||||
q2: NATURAL_32
|
||||
nh: CELL [NATURAL_32]
|
||||
nl: CELL [NATURAL_32]
|
||||
dh: CELL [NATURAL_32]
|
||||
dl: CELL [NATURAL_32]
|
||||
t1: CELL [NATURAL_32]
|
||||
t0: CELL [NATURAL_32]
|
||||
thigh: CELL [NATURAL_32]
|
||||
tlow: CELL [NATURAL_32]
|
||||
sign: INTEGER
|
||||
q: NATURAL_32
|
||||
t: NATURAL_32
|
||||
ssize: INTEGER_32
|
||||
qsize: INTEGER_32
|
||||
i: INTEGER_32
|
||||
cy: NATURAL_32
|
||||
cofactor: SPECIAL [NATURAL_32]
|
||||
cofactor_offset: INTEGER_32
|
||||
op1: SPECIAL [NATURAL_32]
|
||||
op1_offset: INTEGER_32
|
||||
op2: SPECIAL [NATURAL_32]
|
||||
op2_offset: INTEGER_32
|
||||
tp: SPECIAL [NATURAL_32]
|
||||
tp_offset: INTEGER_32
|
||||
s1p: SPECIAL [NATURAL_32]
|
||||
s1p_offset: INTEGER_32
|
||||
temp_special: SPECIAL [NATURAL_32]
|
||||
temp_integer: INTEGER_32
|
||||
op1_count: INTEGER
|
||||
tsize: INTEGER
|
||||
wsize: INTEGER
|
||||
junk: NATURAL_32
|
||||
cy1: NATURAL_32
|
||||
cy2: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
cofactor := cofactor_a
|
||||
cofactor_offset := cofactor_offset_a
|
||||
op1 := op1_a
|
||||
op1_offset := op1_offset_a
|
||||
op1_count := op1_count_a
|
||||
op2 := op2_a
|
||||
op2_offset := op2_offset_a
|
||||
tp := tp_a
|
||||
tp_offset := tp_offset_a
|
||||
s1p := s1p_a
|
||||
s1p_offset := s1p_offset_a
|
||||
ssize := 1
|
||||
sign := sign_a
|
||||
op2_count := op2_count_a
|
||||
orig_s0p := cofactor
|
||||
orig_s0p_offset := cofactor_offset
|
||||
create wp.make_filled (0, op1_count + 1)
|
||||
wp_offset := 0
|
||||
use_double_flag := op1_count > 17
|
||||
from
|
||||
until
|
||||
done
|
||||
loop
|
||||
op2_count := op1_count
|
||||
op2_count := normalize (op2, op2_offset, op2_count)
|
||||
if op2_count <= 1 then
|
||||
done := True
|
||||
else
|
||||
if use_double_flag then
|
||||
uh := op1 [op1_count - 1]
|
||||
vh := op2 [op1_count - 1]
|
||||
ul := op1 [op1_count - 2]
|
||||
vl := op2 [op1_count - 2]
|
||||
cnt := leading_zeros (uh)
|
||||
if cnt /= 0 then
|
||||
uh := (uh |<< cnt).bit_or (ul |>> (32 - cnt))
|
||||
vh := (vh |<< cnt).bit_or (vl |>> (32 - cnt))
|
||||
vl := vl |<< cnt
|
||||
ul := ul |<< cnt
|
||||
if op1_count >= 3 then
|
||||
ul := ul.bit_or (op1 [op1_offset + op1_count - 3] |>> (32 - cnt))
|
||||
vl := vl.bit_or (op2 [op2_offset + op1_count - 3] |>> (32 - cnt))
|
||||
end
|
||||
end
|
||||
a := 1
|
||||
b := 0
|
||||
c := 0
|
||||
d := 1
|
||||
assign_l := 0
|
||||
from
|
||||
done_2 := False
|
||||
create nh.put (0)
|
||||
create nl.put (0)
|
||||
create dh.put (0)
|
||||
create dl.put (0)
|
||||
create thigh.put (0)
|
||||
create tlow.put (0)
|
||||
create t1.put (0)
|
||||
create t0.put (0)
|
||||
until
|
||||
done_2
|
||||
loop
|
||||
sub_ddmmss (dh, dl, vh, vl, 0, c)
|
||||
if dh.item = 0 then
|
||||
done_2 := True
|
||||
else
|
||||
add_ssaaaa (nh, nl, uh, ul, 0, a)
|
||||
q1 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item)
|
||||
add_ssaaaa (dh, dl, vh, vl, 0, d)
|
||||
if dh.item = 0 then
|
||||
done_2 := True
|
||||
else
|
||||
sub_ddmmss (nh, nl, uh, ul, 0, b)
|
||||
q2 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item)
|
||||
if q1 /= q2 then
|
||||
done_2 := True
|
||||
else
|
||||
tac := a + q1 * c
|
||||
tbd := b + q1 * d
|
||||
a := c
|
||||
c := tac
|
||||
b := d
|
||||
d := tbd
|
||||
umul_ppmm (t1, t0, q1, vl)
|
||||
t1.put (t1.item + q1 * vh)
|
||||
sub_ddmmss (thigh, tlow, uh, ul, t1.item, t0.item)
|
||||
uh := vh
|
||||
ul := vl
|
||||
vh := thigh.item
|
||||
vl := tlow.item
|
||||
assign_l := assign_l.bit_not
|
||||
add_ssaaaa (dh, dl, vh, vl, 0, c)
|
||||
sub_ddmmss (nh, nl, uh, ul, 0, a)
|
||||
q1 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item)
|
||||
sub_ddmmss (dh, dl, vh, vl, 0, d)
|
||||
if dh.item = 0 then
|
||||
done_2 := True
|
||||
else
|
||||
add_ssaaaa (nh, nl, uh, ul, 0, b)
|
||||
q2 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item)
|
||||
if q1 /= q2 then
|
||||
done_2 := True
|
||||
else
|
||||
tac := a + q1 * c
|
||||
tbd := b + q1 * d
|
||||
a := c
|
||||
c := tac
|
||||
b := d
|
||||
d := tbd
|
||||
umul_ppmm (t1, t0, q1, vl)
|
||||
t1.put (t1.item + (q1 * vh))
|
||||
sub_ddmmss (thigh, tlow, uh, ul, t1.item, t0.item)
|
||||
uh := vh
|
||||
ul := vl
|
||||
vh := thigh.item
|
||||
vl := tlow.item
|
||||
assign_l := assign_l.bit_not
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if assign_l /= 0 then
|
||||
sign := -sign
|
||||
end
|
||||
else
|
||||
uh := op1 [op1_offset + op1_count - 1]
|
||||
vh := op2 [op2_offset + op1_count - 1]
|
||||
cnt := leading_zeros (uh)
|
||||
if cnt /= 0 then
|
||||
uh := (uh |<< cnt).bit_or (op1 [op1_offset + op1_count - 2] |>> (limb_bits - cnt))
|
||||
vh := (vh |<< cnt).bit_or (op2 [op2_offset + op1_count - 2] |>> (limb_bits - cnt))
|
||||
end
|
||||
a := 1
|
||||
b := 0
|
||||
c := 0
|
||||
d := 1
|
||||
assign_l := 0
|
||||
from
|
||||
done_2 := False
|
||||
until
|
||||
done_2
|
||||
loop
|
||||
if vh - c = 0 or vh + d = 0 then
|
||||
done_2 := True
|
||||
else
|
||||
q := (uh + a) // (vh - c)
|
||||
if q /= (uh - b) // (vh + d) then
|
||||
done_2 := True
|
||||
else
|
||||
t := a + q * c
|
||||
a := c
|
||||
c := t
|
||||
t := b + q * d
|
||||
b := d
|
||||
d := t
|
||||
t := uh - q * vh
|
||||
uh := vh
|
||||
vh := t
|
||||
assign_l := assign_l.bit_not
|
||||
if vh - d = 0 then
|
||||
done_2 := True
|
||||
else
|
||||
q := (uh - a) // (vh + c)
|
||||
if q /= (uh + b) // (vh - d) then
|
||||
done_2 := True
|
||||
else
|
||||
t := a + q * c
|
||||
a := c
|
||||
c := t
|
||||
t := b + q * d
|
||||
b := d
|
||||
d := t
|
||||
t := uh - q * vh
|
||||
uh := vh
|
||||
vh := t
|
||||
assign_l := assign_l.bit_not
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if assign_l /= 0 then
|
||||
sign := -sign
|
||||
end
|
||||
end
|
||||
if b = 0 then
|
||||
tdiv_qr (wp, wp_offset, op1, op1_offset, op1, op1_offset, op1_count, op2, op2_offset, op2_count)
|
||||
tp.copy_data (cofactor, cofactor_offset, tp_offset, ssize)
|
||||
qsize := op1_count - op2_count + 1
|
||||
s1p.fill_with (0, s1p_offset + ssize, s1p_offset + ssize + qsize - 1)
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= qsize
|
||||
loop
|
||||
addmul_1 (tp, tp_offset + i, s1p, s1p_offset, ssize, wp [wp_offset + i], carry)
|
||||
cy := carry.item
|
||||
tp [tp_offset + ssize + i] := cy
|
||||
i := i + 1
|
||||
end
|
||||
ssize := ssize + qsize
|
||||
ssize := ssize - (tp [tp_offset + ssize - 1] = 0).to_integer
|
||||
sign := -sign
|
||||
temp_special := cofactor
|
||||
temp_integer := cofactor_offset
|
||||
cofactor := s1p
|
||||
cofactor_offset := s1p_offset
|
||||
s1p := temp_special
|
||||
s1p_offset := temp_integer
|
||||
temp_special := s1p
|
||||
temp_integer := s1p_offset
|
||||
s1p := tp
|
||||
s1p_offset := tp_offset
|
||||
tp := temp_special
|
||||
tp_offset := temp_integer
|
||||
op1_count := op2_count
|
||||
temp_special := op1
|
||||
temp_integer := op1_offset
|
||||
op1 := op2
|
||||
op1_offset := op2_offset
|
||||
op2 := temp_special
|
||||
op2_offset := temp_integer
|
||||
else
|
||||
if a = 0 then
|
||||
tp.copy_data (op2, op2_offset, tp_offset, op1_count)
|
||||
wp.copy_data (op1, op1_offset, wp_offset, op1_count)
|
||||
submul_1 (wp, wp_offset, op2, op2_offset, op1_count, d, carry)
|
||||
junk := carry.item
|
||||
temp_special := tp
|
||||
temp_integer := tp_offset
|
||||
tp := op1
|
||||
tp_offset := op1_offset
|
||||
op1 := temp_special
|
||||
op1_offset := temp_integer
|
||||
temp_special := wp
|
||||
temp_integer := wp_offset
|
||||
wp := op2
|
||||
wp_offset := op2_offset
|
||||
op2 := temp_special
|
||||
op2_offset := temp_integer
|
||||
tp.copy_data (s1p, s1p_offset, tp_offset, ssize)
|
||||
tsize := ssize
|
||||
tp [tp_offset + ssize] := 0
|
||||
wp.copy_data (cofactor, cofactor_offset, wp_offset, ssize)
|
||||
addmul_1 (wp, wp_offset, s1p, s1p_offset, ssize, d, carry)
|
||||
cy := carry.item
|
||||
wp [wp_offset + ssize] := cy
|
||||
wsize := ssize + (cy /= 0).to_integer
|
||||
temp_special := tp
|
||||
temp_integer := tp_offset
|
||||
tp := cofactor
|
||||
tp_offset := cofactor_offset
|
||||
cofactor := temp_special
|
||||
cofactor_offset := temp_integer
|
||||
temp_special := wp
|
||||
temp_integer := wp_offset
|
||||
wp := s1p
|
||||
wp_offset := s1p_offset
|
||||
s1p := temp_special
|
||||
s1p_offset := temp_integer
|
||||
ssize := wsize.max (tsize)
|
||||
else
|
||||
if assign_l /= 0 then
|
||||
mul_1 (tp, tp_offset, op2, op2_offset, op1_count, b, carry)
|
||||
junk := carry.item
|
||||
submul_1 (tp, tp_offset, op1, op1_offset, op1_count, a, carry)
|
||||
junk := carry.item
|
||||
mul_1 (wp, wp_offset, op1, op1_offset, op1_count, c, carry)
|
||||
junk := carry.item
|
||||
submul_1 (wp, wp_offset, op2, op2_offset, op1_count, d, carry)
|
||||
junk := carry.item
|
||||
else
|
||||
mul_1 (tp, tp_offset, op1, op1_offset, op1_count, a, carry)
|
||||
junk := carry.item
|
||||
submul_1 (tp, tp_offset, op2, op2_offset, op1_count, b, carry)
|
||||
junk := carry.item
|
||||
mul_1 (wp, wp_offset, op2, op2_offset, op1_count, d, carry)
|
||||
junk := carry.item
|
||||
submul_1 (wp, wp_offset, op1, op1_offset, op1_count, c, carry)
|
||||
junk := carry.item
|
||||
end
|
||||
temp_special := tp
|
||||
temp_integer := tp_offset
|
||||
tp := op1
|
||||
tp_offset := op1_offset
|
||||
op1 := temp_special
|
||||
op1_offset := temp_integer
|
||||
temp_special := wp
|
||||
temp_integer := wp_offset
|
||||
wp := op2
|
||||
wp_offset := op2_offset
|
||||
op2 := temp_special
|
||||
op2_offset := temp_integer
|
||||
mul_1 (tp, tp_offset, cofactor, cofactor_offset, ssize, a, carry)
|
||||
cy1 := carry.item
|
||||
addmul_1 (tp, tp_offset, s1p, s1p_offset, ssize, b, carry)
|
||||
cy2 := carry.item
|
||||
cy := cy1 + cy2
|
||||
tp [tp_offset + ssize] := cy
|
||||
tsize := ssize + (cy /= 0).to_integer
|
||||
if cy < cy1 then
|
||||
tp [tp_offset + tsize] := 1
|
||||
wp [wp_offset + tsize] := 0
|
||||
tsize := tsize + 1
|
||||
end
|
||||
mul_1 (wp, wp_offset, s1p, s1p_offset, ssize, d, carry)
|
||||
cy1 := carry.item
|
||||
addmul_1 (wp, wp_offset, cofactor, cofactor_offset, ssize, c, carry)
|
||||
cy2 := carry.item
|
||||
cy := cy1 + cy2
|
||||
wp [wp_offset + ssize] := cy
|
||||
wsize := ssize + (cy /= 0).to_integer
|
||||
if cy < cy1 then
|
||||
wp [wp_offset + wsize] := 1
|
||||
if wsize >= tsize then
|
||||
tp [tp_offset + wsize] := 0
|
||||
end
|
||||
wsize := wsize + 1
|
||||
end
|
||||
temp_special := tp
|
||||
temp_integer := tp_offset
|
||||
tp := cofactor
|
||||
tp_offset := cofactor_offset
|
||||
cofactor := temp_special
|
||||
cofactor_offset := temp_integer
|
||||
temp_special := wp
|
||||
temp_integer := wp_offset
|
||||
wp := s1p
|
||||
wp_offset := s1p_offset
|
||||
s1p := temp_special
|
||||
s1p_offset := temp_integer
|
||||
ssize := wsize.max (tsize)
|
||||
end
|
||||
op1_count := op1_count - (op1 [op1_offset + op1_count - 1] = 0).to_integer
|
||||
end
|
||||
end
|
||||
end
|
||||
if op2_count = 0 then
|
||||
if target /= op1 then
|
||||
target.copy_data (op1, op1_offset, target_offset, op1_count)
|
||||
end
|
||||
ssize := normalize (cofactor, cofactor_offset, ssize)
|
||||
if orig_s0p /= cofactor then
|
||||
orig_s0p.copy_data (cofactor, cofactor_offset, orig_s0p_offset, ssize)
|
||||
end
|
||||
if sign >= 0 then
|
||||
cofactor_count.cofactor_count := ssize
|
||||
else
|
||||
cofactor_count.cofactor_count := -ssize
|
||||
end
|
||||
Result := op1_count
|
||||
else
|
||||
vl := op2 [op2_offset]
|
||||
t := divrem_1 (wp, wp_offset, op1, op1_offset, op1_count, vl)
|
||||
tp.copy_data (cofactor, cofactor_offset, tp_offset, ssize)
|
||||
qsize := op1_count - (wp [wp_offset + op1_count - 1] = 0).to_integer
|
||||
if ssize < qsize then
|
||||
tp.fill_with (0, tp_offset + ssize, qsize - ssize)
|
||||
s1p.fill_with (0, s1p_offset + ssize, qsize)
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= ssize
|
||||
loop
|
||||
addmul_1 (tp, tp_offset + i, wp, wp_offset, qsize, s1p [s1p_offset + i], carry)
|
||||
cy := carry.item
|
||||
tp [tp_offset + qsize + i] := cy
|
||||
i := i + 1
|
||||
end
|
||||
else
|
||||
s1p.fill_with (0, s1p_offset + ssize, s1p_offset + ssize + qsize - 1)
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= qsize
|
||||
loop
|
||||
addmul_1 (tp, tp_offset + i, s1p, s1p_offset, ssize, wp [wp_offset + i], carry)
|
||||
cy := carry.item
|
||||
tp [tp_offset + ssize + i] := cy
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
ssize := ssize + qsize
|
||||
ssize := ssize - (tp [tp_offset + ssize - 1] = 0).to_integer
|
||||
sign := -sign
|
||||
temp_special := cofactor
|
||||
temp_integer := cofactor_offset
|
||||
cofactor := s1p
|
||||
cofactor_offset := s1p_offset
|
||||
s1p := temp_special
|
||||
s1p_offset := temp_integer
|
||||
temp_special := s1p
|
||||
temp_integer := s1p_offset
|
||||
s1p := tp
|
||||
s1p_offset := tp_offset
|
||||
tp := temp_special
|
||||
tp_offset := temp_integer
|
||||
ul := vl
|
||||
vl := t
|
||||
from
|
||||
until
|
||||
vl = 0
|
||||
loop
|
||||
q := ul // vl
|
||||
t := ul - q * vl
|
||||
tp.copy_data (cofactor, cofactor_offset, tp_offset, ssize)
|
||||
s1p.fill_with (0, s1p_offset + ssize, s1p_offset + ssize)
|
||||
addmul_1 (tp, tp_offset, s1p, s1p_offset, ssize, q, carry)
|
||||
cy := carry.item
|
||||
tp [tp_offset + ssize] := cy
|
||||
ssize := ssize + 1
|
||||
ssize := ssize - (tp [tp_offset + ssize - 1] = 0).to_integer
|
||||
sign := -sign
|
||||
temp_special := cofactor
|
||||
temp_integer := cofactor_offset
|
||||
cofactor := s1p
|
||||
cofactor_offset := s1p_offset
|
||||
s1p := temp_special
|
||||
s1p_offset := temp_integer
|
||||
temp_special := s1p
|
||||
temp_integer := s1p_offset
|
||||
s1p := tp
|
||||
s1p_offset := tp_offset
|
||||
tp := temp_special
|
||||
tp_offset := temp_integer
|
||||
ul := vl
|
||||
vl := t
|
||||
end
|
||||
target [target_offset] := ul
|
||||
ssize := normalize (cofactor, cofactor_offset, ssize)
|
||||
if orig_s0p /= cofactor then
|
||||
orig_s0p.copy_data (cofactor, cofactor_offset, orig_s0p_offset, ssize)
|
||||
end
|
||||
if sign >= 0 then
|
||||
cofactor_count.cofactor_count := ssize
|
||||
else
|
||||
cofactor_count.cofactor_count := -ssize
|
||||
end
|
||||
Result := 1
|
||||
end
|
||||
end
|
||||
|
||||
gcdext (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; cofactor: SPECIAL [NATURAL_32]; cofactor_offset: INTEGER; cofactor_count: TUPLE [cofactor_count: INTEGER]; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER; op2_count: INTEGER): INTEGER
|
||||
require
|
||||
op1_count >= op2_count
|
||||
op2_count >= 0
|
||||
op1.valid_index (op1_offset)
|
||||
op1.valid_index (op1_offset + op1_count - 0)
|
||||
op1 [op1_offset + op1_count - 1] /= 0
|
||||
op2.valid_index (op2_offset)
|
||||
op2.valid_index (op2_offset + op2_count - 0)
|
||||
op1 [op1_offset + op1_count - 1] /= 0
|
||||
target.valid_index (target_offset)
|
||||
target.valid_index (target_offset + op1_count - 1)
|
||||
cofactor.valid_index (cofactor_offset)
|
||||
cofactor.valid_index (cofactor_offset + op1_count - 1)
|
||||
local
|
||||
orig_n: INTEGER
|
||||
do
|
||||
orig_n := op2_count
|
||||
Result := basic_gcdext (target, target_offset, cofactor, cofactor_offset, cofactor_count, op1, op1_offset, op1_count, op2, op2_offset, op2_count)
|
||||
end
|
||||
|
||||
modexact_1c_odd (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; d: NATURAL_32; orig_c: NATURAL_32): NATURAL_32
|
||||
require
|
||||
op1_count >= 1
|
||||
d.bit_test (0)
|
||||
local
|
||||
s: NATURAL_32
|
||||
h: CELL [NATURAL_32]
|
||||
l: CELL [NATURAL_32]
|
||||
inverse: NATURAL_32
|
||||
dummy: CELL [NATURAL_32]
|
||||
dmul: NATURAL_32
|
||||
c: CELL [NATURAL_32]
|
||||
i: INTEGER
|
||||
do
|
||||
create l.put (0)
|
||||
create c.put (orig_c)
|
||||
create h.put (0)
|
||||
create dummy.put (0)
|
||||
if op1_count = 1 then
|
||||
s := op1 [op1_offset]
|
||||
if s > c.item then
|
||||
l.put (s - c.item)
|
||||
h.put (l.item \\ d)
|
||||
if h.item /= 0 then
|
||||
h.put (d - h.item)
|
||||
end
|
||||
else
|
||||
l.put (c.item - s)
|
||||
h.put (l.item \\ d)
|
||||
end
|
||||
Result := h.item
|
||||
else
|
||||
inverse := modlimb_invert (d)
|
||||
dmul := d
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= op1_count - 1
|
||||
loop
|
||||
s := op1 [op1_offset + i]
|
||||
subc_limb (c, l, s, c.item)
|
||||
l.put (l.item * inverse)
|
||||
umul_ppmm (h, dummy, l.item, dmul)
|
||||
c.put (c.item + h.item)
|
||||
i := i + 1
|
||||
end
|
||||
s := op1 [op1_offset + i]
|
||||
if s <= d then
|
||||
l.put (c.item - s)
|
||||
if c.item < s then
|
||||
l.put (l.item + d)
|
||||
end
|
||||
Result := l.item
|
||||
else
|
||||
subc_limb (c, l, s, c.item)
|
||||
l.put (l.item * inverse)
|
||||
umul_ppmm (h, dummy, l.item, dmul)
|
||||
c.put (c.item + h.item)
|
||||
Result := c.item
|
||||
end
|
||||
end
|
||||
ensure
|
||||
orig_c < d implies Result < d
|
||||
orig_c >= d implies Result <= d
|
||||
end
|
||||
|
||||
preinv_mod_1 (up: SPECIAL [NATURAL_32]; up_offset: INTEGER; un: INTEGER; d: NATURAL_32; dinv: NATURAL_32): NATURAL_32
|
||||
require
|
||||
un >= 1
|
||||
d.bit_test (31)
|
||||
local
|
||||
i: INTEGER
|
||||
n0: NATURAL_32
|
||||
r: CELL [NATURAL_32]
|
||||
dummy: CELL [NATURAL_32]
|
||||
do
|
||||
create r.put (up [up_offset + un - 1])
|
||||
create dummy.put (0)
|
||||
if r.item >= d then
|
||||
r.put (r.item - d)
|
||||
end
|
||||
from
|
||||
i := un - 2
|
||||
until
|
||||
i < 0
|
||||
loop
|
||||
n0 := up [up_offset + i]
|
||||
udiv_qrnnd_preinv (dummy, r, r.item, n0, d, dinv)
|
||||
i := i - 1
|
||||
end
|
||||
Result := r.item
|
||||
end
|
||||
|
||||
redc_basecase (cp: SPECIAL [NATURAL_32]; cp_offset: INTEGER; mp: SPECIAL [NATURAL_32]; mp_offset: INTEGER; n: INTEGER; n_prim: NATURAL_32; tp: SPECIAL [NATURAL_32]; tp_offset_a: INTEGER)
|
||||
local
|
||||
cy: NATURAL_32
|
||||
q: NATURAL_32
|
||||
j: INTEGER
|
||||
tp_offset: INTEGER
|
||||
junk: NATURAL_32
|
||||
carry: CELL [NATURAL_32]
|
||||
do
|
||||
create carry.put (0)
|
||||
tp_offset := tp_offset_a
|
||||
from
|
||||
j := 0
|
||||
until
|
||||
j >= n
|
||||
loop
|
||||
q := tp [tp_offset] * n_prim
|
||||
addmul_1 (tp, tp_offset, mp, mp_offset, n, q, carry)
|
||||
tp [tp_offset] := carry.item
|
||||
tp_offset := tp_offset + 1
|
||||
j := j + 1
|
||||
end
|
||||
add_n (cp, cp_offset, tp, tp_offset, tp, tp_offset - n, n, carry)
|
||||
cy := carry.item
|
||||
if cy /= 0 then
|
||||
sub_n (cp, cp_offset, cp, cp_offset, mp, mp_offset, n, carry)
|
||||
junk := carry.item
|
||||
end
|
||||
end
|
||||
|
||||
subc_limb (cout: CELL [NATURAL_32]; w: CELL [NATURAL_32]; x: NATURAL_32; y: NATURAL_32)
|
||||
do
|
||||
w.put (x - y)
|
||||
cout.put ((w.item > x).to_integer.to_natural_32)
|
||||
end
|
||||
|
||||
invert_gf (target: SPECIAL [NATURAL_32] target_offset: INTEGER op1_a: SPECIAL [NATURAL_32] op1_offset: INTEGER op1_count_a: INTEGER op2_a: SPECIAL [NATURAL_32] op2_offset: INTEGER op2_count_a: INTEGER)
|
||||
-- Invert `op1' over `op2' using the extended euclidian algorithm in F2M
|
||||
require
|
||||
op2_count_a > 0
|
||||
op1_count_a >= 0
|
||||
op1_count_a <= op2_count_a;
|
||||
(op1_count_a = op2_count_a) implies cmp (op1_a, op1_offset, op2_a, op2_offset, op2_count_a) <= 0
|
||||
local
|
||||
op1: SPECIAL [NATURAL_32]
|
||||
op1_count: INTEGER
|
||||
op1_leading_zeros: INTEGER
|
||||
op2: SPECIAL [NATURAL_32]
|
||||
op2_count: INTEGER
|
||||
op2_leading_zeros: INTEGER
|
||||
tmp_special: SPECIAL [NATURAL_32]
|
||||
tmp_integer: INTEGER
|
||||
g1: SPECIAL [NATURAL_32]
|
||||
g1_count: INTEGER
|
||||
g2: SPECIAL [NATURAL_32]
|
||||
g2_count: INTEGER
|
||||
operand_sizes: INTEGER
|
||||
left_shift_amount: INTEGER
|
||||
do
|
||||
operand_sizes := op2_count_a
|
||||
op1_count := op1_count_a
|
||||
op2_count := op2_count_a
|
||||
create op1.make_filled (0, operand_sizes + operand_sizes)
|
||||
create op2.make_filled (0, operand_sizes + operand_sizes)
|
||||
op1.copy_data (op1_a, op1_offset, 0, op1_count.min (operand_sizes))
|
||||
op2.copy_data (op2_a, op2_offset, 0, op2_count.min (operand_sizes))
|
||||
create g1.make_filled (0, operand_sizes + operand_sizes)
|
||||
create g2.make_filled (0, operand_sizes + operand_sizes)
|
||||
g1 [0] := 1
|
||||
g1_count := 1
|
||||
g2_count := 0
|
||||
from
|
||||
until
|
||||
op1_count = 0
|
||||
loop
|
||||
op1_leading_zeros := leading_zeros (op1 [op1_count - 1])
|
||||
op2_leading_zeros := leading_zeros (op2 [op2_count - 1])
|
||||
if op1_count < op2_count or (op1_count = op2_count and op1_leading_zeros > op2_leading_zeros) then
|
||||
tmp_special := op1
|
||||
op1 := op2
|
||||
op2 := tmp_special
|
||||
tmp_special := g1
|
||||
g1 := g2
|
||||
g2 := tmp_special
|
||||
tmp_integer := op1_count
|
||||
op1_count := op2_count
|
||||
op2_count := tmp_integer
|
||||
tmp_integer := op1_leading_zeros
|
||||
op1_leading_zeros := op2_leading_zeros
|
||||
op2_leading_zeros := tmp_integer
|
||||
end
|
||||
if op1_count /= op2_count or (op1_count = op2_count and op1_leading_zeros /= op2_leading_zeros) then
|
||||
left_shift_amount := (op1_count - op2_count) * limb_bits + op2_leading_zeros - op1_leading_zeros
|
||||
bit_xor_lshift (op1, 0, op1, 0, op1_count, op2, 0, op2_count, left_shift_amount)
|
||||
bit_xor_lshift (g1, 0, g1, 0, operand_sizes, g2, 0, operand_sizes, left_shift_amount)
|
||||
else
|
||||
bit_xor (op1, 0, op1, 0, op1_count, op2, 0, op2_count)
|
||||
bit_xor (g1, 0, g1, 0, operand_sizes, g2, 0, operand_sizes)
|
||||
end
|
||||
op1_count := normalize (op1, 0, op1_count)
|
||||
op2_count := normalize (op2, 0, op2_count)
|
||||
end
|
||||
target.copy_data (g2, 0, target_offset, operand_sizes)
|
||||
end
|
||||
end
|
||||
52
contrib/ise_library/math/eapml/facilities/special_sizing.e
Normal file
52
contrib/ise_library/math/eapml/facilities/special_sizing.e
Normal file
@@ -0,0 +1,52 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_SIZING}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "Whatever you do will be insignificant, but it is very important that you do it. - Mahatma Gandhi"
|
||||
|
||||
deferred class
|
||||
SPECIAL_SIZING
|
||||
|
||||
inherit
|
||||
LIMB_MANIPULATION
|
||||
MP_BASES
|
||||
|
||||
feature
|
||||
|
||||
sizeinbase (source: SPECIAL [NATURAL_32]; source_offset: INTEGER; size: INTEGER; base: INTEGER): INTEGER
|
||||
require
|
||||
size >= 0
|
||||
base >= 2
|
||||
local
|
||||
lb_base: INTEGER
|
||||
count: INTEGER
|
||||
total_bits: INTEGER
|
||||
do
|
||||
if size = 0 then
|
||||
Result := 1
|
||||
else
|
||||
count := leading_zeros (source [source_offset + size - 1])
|
||||
total_bits := size * limb_bits - count
|
||||
if pow2_p (base.to_natural_32) then
|
||||
lb_base := big_base (base).to_integer_32
|
||||
Result := (total_bits + lb_base - 1) // lb_base
|
||||
else
|
||||
Result := ((total_bits * chars_per_bit_exactly (base)) + 1).truncated_to_integer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sizeinbase_2exp (ptr: SPECIAL [NATURAL_32]; ptr_offset: INTEGER; ptr_count: INTEGER; base2exp: INTEGER): INTEGER
|
||||
require
|
||||
ptr_count > 0
|
||||
ptr [ptr_offset + ptr_count - 1] /= 0
|
||||
local
|
||||
count: INTEGER
|
||||
totbits: INTEGER
|
||||
do
|
||||
count := leading_zeros (ptr [ptr_offset + ptr_count - 1])
|
||||
totbits := ptr_count * limb_bits - count
|
||||
Result := (totbits + base2exp - 1) // base2exp
|
||||
end
|
||||
end
|
||||
37
contrib/ise_library/math/eapml/facilities/special_utility.e
Normal file
37
contrib/ise_library/math/eapml/facilities/special_utility.e
Normal file
@@ -0,0 +1,37 @@
|
||||
note
|
||||
description: "Summary description for {NUMBER_UTILITY}."
|
||||
author: "Colin LeMahieu"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
quote: "If a law is unjust, a man is not only right to disobey it, he is obligated to do so. - Thomas Jefferson"
|
||||
|
||||
deferred class
|
||||
SPECIAL_UTILITY
|
||||
|
||||
feature
|
||||
|
||||
normalize (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER): INTEGER
|
||||
do
|
||||
from
|
||||
Result := op1_count
|
||||
until
|
||||
Result <= 0 or op1 [op1_offset + Result - 1] /= 0
|
||||
loop
|
||||
Result := Result - 1
|
||||
end
|
||||
end
|
||||
|
||||
reverse (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; source: SPECIAL [NATURAL_32]; source_offset: INTEGER; count: INTEGER)
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i >= count
|
||||
loop
|
||||
target [target_offset + i] := source [source_offset + count - 1 - i]
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user