Re: Question About Z-Level Number Thingie
- Posted by "Boehme, Gabriel" <gboehme at POSTOFFICE.MUSICLAND.COM> Dec 08, 1999
- 347 views
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 ----------