 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
apocalypse~r
Joined: 21 Jun 2007 Posts: 24
|
Posted: Tue Feb 26, 2008 11:49 pm Post subject: NumBaseChng function v2.1: supports fractions, negatives |
|
|
converts any number (within the scripts number size limits) to and from any desired base between 2 and 64, including but not limited to decimal, hexadecimal, and binary. 0 - 9 are 0 - 9, a - z are 10 - 35, A - Z are 36 - 61, / is 62, and * is 63
It now supports decimals. Decimals can be in any base.
it includes errorlevel support - (0- no problem, 2- starting base was not integer [aborted], 3- ending base was not integer [aborted])
errorlevel used to bring up 1 if the input number was not an integer (checked for decimal point), but floating point numbers are now supported.
syntax- numbasechng(number, starting base, ending base)
because functions treat params as expressions, if your number is higher than base 10 and contains non number characters (letters etc), it must be enclosed in quotes. for numbers containing only 0 - 9, the quotes are optional. letters in %number% ARE CASE SENSITIVE. F != f. (f = 15, F = 41) also - remove the 0x prefix when working with hex, as this function does not (yet) support it.
syntax for floats is basically normal syntax:
numbasechng(123.123, 4, 16) = 1b.6c
numbasechng("f.f", 16, 10) = 15.9375
| Code: | numbasechng(number, base, endbase = 10)
{
if (base > 64)
{
errorlevel = -2
return
}
else if base = 16
stringreplace, number, number, 0x,
if (endbase > 64)
{
errorlevel = -3
return
}
if number = 0
return, 0
setformat, float, 0.15
stringcasesense, on
errorlevel = 0
if base is not integer
{
errorlevel = 2
return
}
if endbase is not integer
{
errorlevel = 3
return
}
ifinstring, number, -
{
neg = -
stringreplace, number, number, -, , A
}
total = 0
ifinstring, number, .
{
dedec := instr(number, ".", 0, 1)
decimal := substr(number, dedec)
decimalb10 := 0
number := substr(number, 1, dedec - 1)
decimalvalue = .
loop, parse, decimal
{
if a_index = 1
continue
char := a_loopfield
gosub, swapout
decimalb10 := decimalb10 + (char * (base ** -(a_index - 1)))
}
if endbase <> 10
{
loop
{
char := floor(.00000000000001 + decimalb10 / (1 / ((endbase ** a_index))))
decimalb10 := decimalb10 - (char * (1 / ((endbase ** a_index))))
gosub, unswap
decimalvalue = %decimalvalue%%char%
if a_index > 10
break
}
}
else
decimalvalue := decimalb10
loop, parse, decimalvalue, %a_space%, 0
decimalvalue := a_loopfield
}
length := strlen(number)
loop, parse, number,
{
char := a_loopfield
gosub, swapout
total := total + char * (base ** (length - a_index))
}
if endbase = 10
{
if not decimal
return, neg . total
else
return, neg . total . decimalvalue
}
newlength := ceil(log(floor(total) + 1) / log(endbase))
loop, %newlength%
{
char := floor(total / (endbase ** (newlength - a_index)))
total := total - char * endbase ** (newlength - a_index)
gosub, unswap
endnumber := endnumber . char
}
if not decimal
return, neg . endnumber
else
return, neg . endnumber decimalvalue
return
swapout:
if char between a and z
char := asc(char) - 87
if char between A and Z
char := asc(char) - 29
if char = /
char := 62
if char = *
char := 63
return
unswap:
if char between 10 and 35
char := chr(char + 87)
if char between 36 and 61
char := chr(char + 29)
if char = 62
char = /
if char = 63
char = *
return
} |
I made the horribly long char replacement subs into easy to work with short ones.
(in version 2.2, i will probably add support for the "0x" hex~ prefix and 'gasp' negative numbers, which it wierds out when passed.)
my name from base64 to base10 is 5068854867484066741 _________________ problems := bugs + errors + glitches
code := (problems != 0) ? debug(code) : celebrate()
Last edited by apocalypse~r on Fri Mar 07, 2008 3:02 am; edited 4 times in total |
|
| Back to top |
|
 |
haichen
Joined: 05 Feb 2007 Posts: 140 Location: Osnabrück, Germany
|
Posted: Wed Feb 27, 2008 12:06 am Post subject: |
|
|
| Do you know Laszlos miraculous long Integer Library? |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Wed Feb 27, 2008 3:10 am Post subject: |
|
|
| In this thread there are a couple of short functions for 1 < base < 37 (one of them is a single line). Maybe you can modify them to extend the range of the acceptable bases. |
|
| Back to top |
|
 |
Oberon
Joined: 18 Feb 2008 Posts: 453
|
Posted: Wed Feb 27, 2008 9:08 am Post subject: |
|
|
| I haven't seen any base functions before, but it's interesting to know how many different methods can be used to do this. |
|
| Back to top |
|
 |
apocalypse~r
Joined: 21 Jun 2007 Posts: 24
|
Posted: Tue Mar 04, 2008 4:35 am Post subject: |
|
|
i can get rid of the horribly long character replacement subs, at least until we get to outrageously huge bases like 100+ _________________ problems := bugs + errors + glitches
code := (problems != 0) ? debug(code) : celebrate() |
|
| Back to top |
|
 |
apocalypse~r
Joined: 21 Jun 2007 Posts: 24
|
Posted: Thu Mar 06, 2008 4:30 am Post subject: special thanks |
|
|
thanks to laszlo, who showed me how to use the chr and asc built in functions to get rid of all the easy number to letter conversions.
edit**
v2.1 released, includes support for "0x" hex prefix, and support for negative numbers. also now behaves correctly when passed number 0. _________________ problems := bugs + errors + glitches
code := (problems != 0) ? debug(code) : celebrate() |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|