AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

NumBaseChng function v2.1: supports fractions, negatives

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
apocalypse~r



Joined: 21 Jun 2007
Posts: 24

PostPosted: Tue Feb 26, 2008 11:49 pm    Post subject: NumBaseChng function v2.1: supports fractions, negatives Reply with quote

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
View user's profile Send private message
haichen



Joined: 05 Feb 2007
Posts: 140
Location: Osnabrück, Germany

PostPosted: Wed Feb 27, 2008 12:06 am    Post subject: Reply with quote

Do you know Laszlos miraculous long Integer Library?
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Wed Feb 27, 2008 3:10 am    Post subject: Reply with quote

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
View user's profile Send private message
Oberon



Joined: 18 Feb 2008
Posts: 453

PostPosted: Wed Feb 27, 2008 9:08 am    Post subject: Reply with quote

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
View user's profile Send private message
apocalypse~r



Joined: 21 Jun 2007
Posts: 24

PostPosted: Tue Mar 04, 2008 4:35 am    Post subject: Reply with quote

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
View user's profile Send private message
apocalypse~r



Joined: 21 Jun 2007
Posts: 24

PostPosted: Thu Mar 06, 2008 4:30 am    Post subject: special thanks Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group