Re: Question About Z-Level Number Thingie
Colin Taylor wrote:
>Here is a slight improvement of my original routine (recursion retained)
>and a slight improvement of your second routine (doesn't need the reverse()
>function). It passes the sanity test, but still doesn't like negative
>numbers.
>
>constant CHAR = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
>
>function convert_base(integer num, integer base)
> sequence out_str
> out_str = ""
> if num >= base then
> out_str = convert_base(floor(num/base), base)
> end if
> return out_str & CHAR[remainder(num, base)+1]
>end function
<PICKYMODE=PETPEEVE>
Maybe this is just me, but I don't see why the convert_base() function has
to be recursive. Every time it calls itself, it has to re-allocate space for
num, base and out_str. I guess I don't see how that's "better" -- especially
since base retains the same value on each recursive call, which is rather
inefficient. Generally, I'm pretty sure it's more efficient to code a
routine with "while" loop, rather than trying to make it recursive. (If I'm
wrong, though, let me know!)
</PICKYMODE>
And as for handling negative values, well, I guess I'm just going to "cheat"
on this one. The two's complement stuff would only work for base-2 derived
number systems, so I'm just adding a sign character to the value. That way,
it'll work no matter what number system we're using.
>function read_base(sequence num, integer base)
> integer out_num, len
> len = length(num)
> out_num = 0
> for i = 1 to len do
> out_num += (find(num[i], CHAR)-1)*power(base, len-i)
> end for
> return out_num
>end function
Cool, thanks for getting that reverse() call outta there!
-- my revised version, covering the full range of Euphoria integers positive
and negative...
constant NUM_CHAR = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
type base_type(integer x)
return x >= 2 and x <= length(NUM_CHAR)
end type
function int_to_base_n(integer int, base_type base)
integer sign
sequence base_n
if int < 0 then
sign = '-'
int = -int
else
sign = '+'
end if
base_n = ""
while int >= base do
base_n = prepend(base_n, NUM_CHAR[remainder(int,base)+1])
int = floor(int/base)
end while
return sign & prepend(base_n, NUM_CHAR[int+1])
end function
function base_n_to_int(sequence base_n, base_type base)
integer len, int
len = length(base_n)
int = 0
for pos = 2 to len do
int += (find(base_n[pos], NUM_CHAR)-1) * power(base, len-pos)
end for
if base_n[1] = '+' then
return int
elsif base_n[1] = '-' then
return -int
end if
end function
-- sanity test
sequence string
integer result
for base = 2 to 36 do
printf(1, "[Base %d]\n", base)
for number = -100 to 100 do
string = int_to_base_n(number, base)
printf(1, "%s\n", {string})
result = base_n_to_int(string, base)
if number != result then
printf(1, "%d != %d", {number, result})
abort(0)
end if
end for
puts(1, '\n')
end for
puts(1, "\nYay!\n")
Now, if somebody could figure out how to handle floating-point values with
this thing...
Hep yadda,
Gabriel Boehme
----------
We'll never get rich by hard work; but, we'll never get rich without it.
Robert Fripp
----------
|
Not Categorized, Please Help
|
|