Answering your question "because the values are different in the two outputs?".
That function pow()
that defined in Ocaml works well with small numbers:
# pow(2,5) ;;
- : int = 32
However in the required magnitude in its calculation bs=31
and tam=412
the result sometimes exceeds the value of max_int
:
# max_int;;
- : int = 4611686018427387903
Breaking the numerical limit and returning a negative value, remembering positive power of positive integers the result is always positive.
# pow(31,412) ;;
- : int = -1355500415
Already in python the builtin pow()
will return the correct value because in python there is virtually no limit to integers:
>>> print(pow(31,412))
276069138324941945105491334106743548343721891253395677647688980210268338479815494895702857569705905259215554766122880414081265412222862455070422343941123563226292693898588710424868593004715576400093926321790564436401576623753610968630429707481035503096221766405055115180414065291029160680597540318300168902837206474368389783537831824941035360031248630200395997664286279876185196611747109383548663603552453004476274809140462798037718731829815781875721556412228287401860555521034466663555186417962593312862133585901989904028712225121222048901049818453241421257430604049981206904806269761521337270272284591644143301761
In Ocaml instead of performing these calculations with the type int
use some numerical type of arbitrary precision.
Editing:
As AP restricted the function domain, another problem appeared. There is a difference in the way that Ocaml treats the operator mod
and the way Python treats the operator %
.
To definition of module says that given two positive numbers, a
and b
, a module b
(abbreviated as mod b
) is the remainder of euclidean division of a
for b
:
a = bq + r
Where:
a
is the dividend.
b
is the divider.
q
is the quotient.
r
is the rest.
When dividend and divisor are positive all right, the problem is when one of the operators is negative and two results are mathematically possible.
Another factor that influences the result is the way languages treat the entire division:
- In Ocaml the entire division is rounded to 0, which makes the module result always have the same signal as the dividend.
- In Python the entire division always rounds down (towards negative infinity), which makes the module result always have the same signal as the divisor.
An example of divergence would be module of the division of -684
for 13
:
In Ocaml:
# -684 mod 13 ;;
- : int = -8
Python:
>>> -684 % 13
5
So it’s two solutions. One solution would be to make the code Ocaml behave like the code Python, the other solution would be to make the code Python behave like the code Ocaml.
First Alternative: Making Code Ocaml behave like Python:
To make the operator Ocaml mod
present the same result as in Python the operator must be reimplemented:
# let (mod) x y = let res = x mod y in if res < 0 then res + y else res;;
Or in your code:
let rec pow((x:int), (y:int)) : int =
if y=0 then
1
else
x * pow(x,y-1)
;;
let (mod) x y = let res = x mod y in if res < 0 then res + y else res;;
let pr = 13;;
let bs = 31;;
let getvalor num ch1 ch2 tam =
(num * bs + int_of_char(ch1) - int_of_char(ch2) * (pow(bs, tam) mod pr)) mod pr
;;
Resulting:
# print_int (getvalor 1 'A' 'A' 2);;
5
Second Alternative: Making Code Python behave like Ocaml:
In that case it is sufficient to replace the operator Ocaml mod
for its equivalent Python math.fmod()
from math import fmod
def int_of_char(char):
return ord(char)
def getvalor(num, ch1, ch2, bs, length, nmb2):
return int(fmod(num * bs + int_of_char(ch1) - int_of_char(ch2) * fmod(pow(bs, length), nmb2), nmb2))
Resulting:
>>>print (getvalor (1,'A','A',31,2,13))
-8
Using one or another solution depends on your intention.
How you implemented this potentiation between integers in Ocaml?
– Augusto Vasques
forgot to put. I already did update
– manuel
Obs for those who do not know the Ocaml language, try to do
2 ** 3
or else, if my memory doesn’t fail me, something like thisfloat_of_int 2 ** float_of_int 3|> int_of_float
– Augusto Vasques