InvisionFree - Free Forum Hosting
InvisionFree gives you all the tools to create a successful discussion community.

Learn More · Register for Free
Welcome to Dozensonline. We hope you enjoy your visit.
You're currently viewing our forum as a guest. This means you are limited to certain areas of the board and there are some features you can't use. If you join our community, you'll be able to access member-only sections, and use many member-only features such as customizing your profile, sending personal messages, and voting in polls. Registration is simple, fast, and completely free.
Join our community!
If you're already a member please log in to your account to access all of our features:

Name:   Password:


 

 Base conversion program
Dan
Posted: Aug 11 2005, 05:03 AM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



Here's a little Python program I wrote for converting numbers from one base to another, with unlimited precision. Thought you might find it useful.

CODE
#!/usr/bin/env python
# -*- coding: latin-1 -*-

"""Command-line base-conversion utility.

This program converts its arguments from one mathematical base to another.
Floating-point and scientific notation (mant@exp) are supported.

USAGE

   baseconv [-i base] [-o base] [{-e|-f|-g} precision] number ...

OPTIONS

  -i base
     the base in which the arguments are written (default: 10)
  -o base
     the base in which to display the output (default: 10)
  -e precision
     display results in exponential format, e.g. 1.234567@-3
     precision = the number of "decimal places" in the mantissa
  -f precision
     display results in fixed-point format, e.g. 0.001235
     precision = the number of "decimal places"
  -g precision
     display reults in -e or -f format, whichever is shorter
     precision = the number of significant digits
"""

from __future__ import division

import getopt
import math
import sys
from rational import Rational

DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'


def _atoi(string, base):
  """Convert a string to the corresponding number."""
  return int(string, base)


def _itoa(num, base):
  """Return the string representation of a number in the given base."""

  # to avoid having _itoa(0) == ''
  if num == 0:
     return DIGITS[0]

  # if num is negative, convert the abs and add the sign later
  negative = num < 0
  if negative:
     num = -num

  # build the numeral one digit at a time, from right to left
  digits = []
  while num:
     num, last_digit = divmod(num, base)
     digits.append(DIGITS[last_digit])
  if negative:
     digits.append('-')
  return ''.join(reversed(digits))


def str2num(string, base):
  """Convert a string to its numeric representation as a Rational."""

  string = ''.join(string.split()) # remove all whitespace

  # Check whether the number is negative
  negative = string.startswith('-')
  if negative:
     string = string[1:]

  # Check whether the number is in scientific notation
  # number = mantissa * base ** exponent
  if '@' in string:
     mantissa, exponent = string.split('@')
     exponent = _atoi(exponent, base)
  else:
     mantissa = string
     exponent = 0

  # Check whether the number contains a radix point
  if '.' in mantissa:
     int_part, frac_part = mantissa.split('.')
     exponent -= len(frac_part)
     mantissa = int_part + frac_part

  mantissa = _atoi(mantissa, base)
  if negative:
     mantissa = -mantissa
  if exponent < 0:
     return Rational(mantissa, base ** (-exponent))
  else:
     return Rational(mantissa * base ** exponent)


def _frexp(x, base):
  if x == 0:
     return 0, 0
  mantissa = x
  exponent = 0
  while abs(mantissa) < 1:
     mantissa *= base
     exponent -= 1
  while abs(mantissa) >= base:
     mantissa /= base
     exponent += 1
  return mantissa, exponent


def _format_f(x, base, precision):

  negative = x < 0
  if negative:
     sign = '-'
     x = -x
  else:
     sign = ''

  multiplier = base ** precision
  x *= multiplier
  x = int(x.round(1))
  if precision == 0:
     return _itoa(x, base)
  ipart, fpart = divmod(x, multiplier)
  return '%s%s.%s' % (sign, _itoa(ipart, base),
                      _itoa(fpart, base).zfill(precision))


def _format_e(x, base, precision):
  mantissa, exponent = _frexp(x, base)
  while True:
     result = '%s@%s' % (_format_f(mantissa, base, precision),
                         _itoa(exponent, base))
     # check to see whether rounding created a denormalized number
     if result.lstrip('-').find('.') > 1:
        mantissa /= base
        exponent += 1
     else:
        return result


def _format_g(x, base, precision):
  mantissa, exponent = _frexp(x, base)
  f_format = _format_f(x, base, max(0, precision - exponent - 1))
  e_format = _format_e(x, base, precision - 1)
  if len(e_format) < len(f_format):
     return e_format
  else:
     return f_format


def num2str(x, base, format='g', precision=None):
  """Converts a number to its string representation in the given base."""
  if precision is None:
     precision = int(math.log(2 ** 53, base))
  if not isinstance(x, Rational):
     x = Rational.from_exact_float(x)
  if format == 'f':
     return _format_f(x, base, precision)
  elif format == 'e':
     return _format_e(x, base, precision)
  elif format == 'g':
     return _format_g(x, base, precision)
  else:
     raise ValueError('Unsupported format: %%%s' % format)


def _main(argv=sys.argv):
  opts, args = getopt.getopt(argv[1:], 'e:f:g:i:o:', ['help'])
  opts = dict(opts)
  if '--help' in opts:
     print __doc__
  else:
     try:
        input_base = int(opts.get('-i', 10))
        output_base = int(opts.get('-o', 10))
     except ValueError:
        print >>sys.stderr, 'Error: Bases must be integers.'
        return 1
     if (input_base < 2 or input_base > 36 or
         output_base < 2 or output_base > 36):
        print >>sys.stderr, 'Error: Base must be 2-36.'
        return 1
     format_e = '-e' in opts
     format_f = '-f' in opts
     format_g = '-g' in opts
     precision = None
     if format_e + format_f + format_g > 1:
        print >>sys.stderr, 'Error: Only one format can be specified.'
        return 1
     elif format_e:
        format = 'e'
     elif format_f:
        format = 'f'
     elif format_g:
        format = 'g'
     else:
        format = 'g'
        precision = int(math.log(2 ** 53, output_base))
     if precision is None:
        precision = opts['-' + format]
        try:
           precision = int(precision)
        except ValueError:
           print >>sys.stderr, 'Error: Precision must be an integer.'
           return 1
     if precision < 0:
        print >>sys.stderr, 'Error: Precision must be nonnegative.'
        return 1
     return_value = 0
     for number in args:
        try:
           number = str2num(number, input_base)
           print num2str(number, output_base, format, precision)
        except (ValueError, TypeError), e:
           print >>sys.stderr, 'Invalid number: %s' % number
           return_value = 1
  return 0

if __name__ == '__main__':
  raise SystemExit(_main())


Examples

Convert decimal 123.456 to dozenal:

CODE
~$ baseconv -o12 123.456
A3.557B74854619


Round it to two dozenal places:

CODE
~$ baseconv -o12 -f2 123.456
A3.56


Convert Avogadro's Number to hexadecimal ("@" is used as the scientific notation symbol because "e" is a digit):

CODE
~$ baseconv -o16 6.02214199@23
7.F8618DE5AED9@13


Compute 1/23 (i.e. 0.1 base 23) in dozenal to 36 significant digits

CODE
~$ baseconv -i23 -o12 -g36 0.1
0.0631694842106316948421063169484210632
Top
The Mighty Dozen
Posted: Aug 11 2005, 07:40 PM


Administrator


Group: Admin
Posts: 564
Member No.: 1
Joined: 2-August 05



Okay Dan, I am braindead as far as computer stuff goes. So, how does one use the above program? huh.gif


--------------------
Forum Administrator
Please call me "Bryan", not "Sir/Idiot/Madam/Mighty Dozen"
**

The reason nature seems to test mankind
With cold and stone-hard stares and unmoved mind,
Is just to make him see what's plainly true:
He's like an animal, nay, is one too.
Top
Dan
Posted: Aug 12 2005, 02:53 AM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



QUOTE (The Mighty Dozen @ Aug 11 2005, 02:40 PM)
Okay Dan, I am braindead as far as computer stuff goes. So, how does one use the above program?  huh.gif

First, you'll need to install Python and download the rational numbers module. Copy the contents of that big code box into your text editor (making sure to preserve the indentation), and save it as "baseconv.py".

The program is meant to be executed from the command prompt. The syntax for it is: python baseconv.py options number_to_convert

The possible options are:
  • -i base -- specifies the base to convert from. Must be an integer between 2 and 36, inclusive. The default is 10.
  • -o base -- specifies the base to convert to. Must be an integer between 2 and 36, inclusive. The default is 10.
  • -f precision -- displays the output in fixed-point notation with precision digits after the radix point. (To round to the nearest integer, use -f0.)
  • -e precision -- displays the output in scientific notation with precision digits after the radix point.
  • -g precision -- displays the output in either -e or -f format, whichever is shorter. Precision indicates the number of significant digits to display.
Top
The Mighty Dozen
Posted: Aug 12 2005, 01:29 PM


Administrator


Group: Admin
Posts: 564
Member No.: 1
Joined: 2-August 05



Cheers, Dan. I'll give it a go when I get a spare ten minutes smile.gif


--------------------
Forum Administrator
Please call me "Bryan", not "Sir/Idiot/Madam/Mighty Dozen"
**

The reason nature seems to test mankind
With cold and stone-hard stares and unmoved mind,
Is just to make him see what's plainly true:
He's like an animal, nay, is one too.
Top
Twinbee
Posted: Aug 12 2005, 04:27 PM


Casual Member


Group: Members
Posts: 27
Member No.: 11
Joined: 4-August 05



Dan, if you have time, make it into an exe and give it a GUI smile.gif
Top
The Mighty Dozen
Posted: Aug 12 2005, 04:48 PM


Administrator


Group: Admin
Posts: 564
Member No.: 1
Joined: 2-August 05



QUOTE (Twinbee @ Aug 12 2005, 04:27 PM)
Dan, if you have time, make it into an exe and give it a GUI smile.gif

...and install it for us, while you're at it wink.gif biggrin.gif


--------------------
Forum Administrator
Please call me "Bryan", not "Sir/Idiot/Madam/Mighty Dozen"
**

The reason nature seems to test mankind
With cold and stone-hard stares and unmoved mind,
Is just to make him see what's plainly true:
He's like an animal, nay, is one too.
Top
Dan
Posted: Aug 15 2005, 03:07 AM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



QUOTE (Twinbee @ Aug 12 2005, 11:27 AM)
Dan, if you have time, make it into an exe and give it a GUI smile.gif

I'll put on on my website next week when I re-acquire my domain name.
Top
finlay
Posted: Aug 18 2005, 05:25 PM


Casual Member


Group: Members
Posts: 78
Member No.: 17
Joined: 6-August 05



It's fairly obvious why you've done it, but could you possibly implement a system whereby you could use bases higher than 36?
I'm just about to try it, anyway, and then once my sister's come off msn rolleyes.gif I can try it on the mac, which allegedly comes with python.
Sounds cool. smile.gif

OK it's not working. Some syntax error? Not sure if it's yours or mine.
Top
Dan
Posted: Aug 18 2005, 07:47 PM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



QUOTE (finlay @ Aug 18 2005, 12:25 PM)
OK it's not working. Some syntax error? Not sure if it's yours or mine.

What error are you getting?
Top
finlay
Posted: Aug 20 2005, 05:34 PM


Casual Member


Group: Members
Posts: 78
Member No.: 17
Joined: 6-August 05



QUOTE
:~/Desktop/Downloads/baseconv] finlay% python baseconv.py
Traceback (most recent call last):
File "baseconv.py", line 35, in ?
from rational import Rational
File "/Users/finlay/Desktop/Downloads/baseconv/rational.py", line 194
@staticmethod
^
SyntaxError: invalid syntax

Apparently it's neither yours nor mine, unless I'm somehow mistaken.... :\
Top
Dan
Posted: Aug 20 2005, 06:18 PM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



Top
Dan
Posted: Jul 19 2007, 03:23 AM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



I guess I should explain my use of @ as the separator between the mantissa and exponent.

The usual notation uses "e", but that's a digit in bases fifteen and higher, so I couldn't use it. Or any letter (or digit, of course), because it would be a digit in some base.

I also didn't want to use any of the symbols !"#%&\'()*+,-./:;<=>?[\]^_{|}~ because each of them has a meaning in C (which, along with its descendants C++ and Java, are the most popular programming languages today).

So, that left only 3 characters left on my keyboard: $, @, and `. But "$" is very commonly used with digits, and ` could be confused with the apostrophe, so the only practical choice was @. Coincidentally, it has a slight resemblance to a lowercase "e".
Top
Ged
Posted: Jul 22 2007, 03:16 PM


Casual Member


Group: Members
Posts: 65
Member No.: 16
Joined: 6-August 05



I had the same problem with Python.

However I have written a base conversion programme in GUI using C++,
but it only works on Windows sad.gif

So if anybody is interested in it let me know.


--------------------
Dozenal numbers: ten_doz.JPG or X for Ten, elf_doz.JPG or E for Eleven said as Elv.

Member of :

DSGB http://www.dozenalsociety.org.uk/
DSA http://www.dozenal.org/
Top
Dan
Posted: Jul 23 2007, 12:20 AM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



QUOTE (Ged @ Jul 22 2007, 09:16 AM)
I had the same problem with Python.

Here's one that uses the GMPY rational number class instead of the one I wrote.

CODE
#!/usr/bin/python -Wignore
# -*- coding: latin-1 -*-

"""Command-line base-conversion utility.

This program converts its arguments from one mathematical base to another.
Floating-point and scientific notation (mant@exp) are supported.

USAGE

   baseconv [-i base] [-o base] [{-e|-f|-g} precision] number ...

OPTIONS

  -i base
     the base in which the arguments are written (default: 10)
  -o base
     the base in which to display the output (default: 10)
  -e precision
     display results in exponential format, e.g. 1.234567@-3
     precision = the number of "decimal places" in the mantissa
  -f precision
     display results in fixed-point format, e.g. 0.001235
     precision = the number of "decimal places"
  -g precision
     display reults in -e or -f format, whichever is shorter
     precision = the number of significant digits
"""

from __future__ import division

import getopt
import math
import sys
import gmpy

DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'


def _atoi(string, base):
   """Convert a string to the corresponding number."""
   return int(string, base)


def _itoa(num, base):
   """Return the string representation of a number in the given base."""

   # to avoid having _itoa(0) == ''
   if num == 0:
       return DIGITS[0]

   # if num is negative, convert the abs and add the sign later
   negative = num < 0
   if negative:
       num = -num

   # build the numeral one digit at a time, from right to left
   digits = []
   while num:
       num, last_digit = divmod(num, base)
       digits.append(DIGITS[last_digit])
   if negative:
       digits.append('-')
   return ''.join(reversed(digits))


def str2num(string, base):
   """Convert a string to its numeric representation."""

   string = ''.join(string.split()) # remove all whitespace

   # Check whether the number is negative
   negative = string.startswith('-')
   if negative:
       string = string[1:]

   # Check whether the number is in scientific notation
   # number = mantissa * base ** exponent
   if '@' in string:
       mantissa, exponent = string.split('@')
       exponent = _atoi(exponent, base)
   else:
       mantissa = string
       exponent = 0

   # Check whether the number contains a radix point
   if '.' in mantissa:
       int_part, frac_part = mantissa.split('.')
       exponent -= len(frac_part)
       mantissa = int_part + frac_part

   mantissa = _atoi(mantissa, base)
   if negative:
       mantissa = -mantissa
   if exponent < 0:
       return gmpy.mpq(mantissa, base ** (-exponent))
   else:
       return gmpy.mpq(mantissa * base ** exponent)


def _frexp(num, base):
   """Return (mant, exp) such that num == mant * base ** exp"""
   if num == 0:
       return gmpy.mpq(0), 0
   mantissa = num
   exponent = 0
   while abs(mantissa) < 1:
       mantissa *= base
       exponent -= 1
   while abs(mantissa) >= base:
       mantissa /= base
       exponent += 1
   return gmpy.mpq(mantissa), exponent

def _round(num):
   """Round num to the nearest integer using round-to-even."""
   negative = num < 0
   if negative:
       num = -num
   int_part = long(num)
   frac_part = num - int_part
   if frac_part == gmpy.mpq(1, 2):
       int_part += int_part & 1
   elif frac_part > gmpy.mpq(1, 2):
       int_part += 1
   if negative:
       int_part = -int_part
   return int_part


def _format_f(num, base, precision):
   """Equivalent of '%.*f' % (num, precision) in the given base."""

   negative = num < 0
   if negative:
       sign = '-'
       num = -num
   else:
       sign = ''

   multiplier = base ** precision
   num *= multiplier
   num = _round(num)
   if precision == 0:
       return _itoa(num, base)
   ipart, fpart = divmod(num, multiplier)
   return '%s%s.%s' % (sign, _itoa(ipart, base),
                      _itoa(fpart, base).zfill(precision))


def _format_e(num, base, precision):
   """Equivalent of '%.*e' % (num, precision) in the given base."""
   mantissa, exponent = _frexp(num, base)
   while True:
       result = '%s@%s' % (_format_f(mantissa, base, precision),
                           _itoa(exponent, base))
       # check to see whether rounding created a denormalized number
       if result.lstrip('-').find('.') > 1:
           mantissa /= base
           exponent += 1
       else:
           return result


def _format_g(num, base, precision):
   """Equivalent of '%.*g' % (num, precision) in the given base."""
   exponent = _frexp(num, base)[1]
   f_format = _format_f(num, base, max(0, precision - exponent - 1))
   e_format = _format_e(num, base, precision - 1)
   if len(e_format) < len(f_format):
       return e_format
   else:
       return f_format


def num2str(num, base, format='g', precision=None):
   """Converts a number to its string representation in the given base."""
   if precision is None:
       precision = int(math.log(2 ** 53, base))
   num = gmpy.mpq(num)
   if format == 'f':
       return _format_f(num, base, precision)
   elif format == 'e':
       return _format_e(num, base, precision)
   elif format == 'g':
       return _format_g(num, base, precision)
   else:
       raise ValueError('Unsupported format: %%%s' % format)


def _main(argv=None):
   """Executed when this file is run as a script."""
   if argv is None:
       argv = sys.argv
   opts, args = getopt.getopt(argv[1:], 'e:f:g:i:o:', ['help'])
   opts = dict(opts)
   if '--help' in opts:
       print __doc__
   else:
       try:
           input_base = int(opts.get('-i', 10))
           output_base = int(opts.get('-o', 10))
       except ValueError:
           print >> sys.stderr, 'Error: Bases must be integers.'
           return 1
       if (input_base < 2 or input_base > 36 or
           output_base < 2 or output_base > 36):
           print >> sys.stderr, 'Error: Base must be 2-36.'
           return 1
       format_e = '-e' in opts
       format_f = '-f' in opts
       format_g = '-g' in opts
       precision = None
       if format_e + format_f + format_g > 1:
           print >> sys.stderr, 'Error: Only one format can be specified.'
           return 1
       elif format_e:
           format = 'e'
       elif format_f:
           format = 'f'
       elif format_g:
           format = 'g'
       else:
           format = 'g'
           precision = int(math.log(2 ** 53, output_base))
       if precision is None:
           precision = opts['-' + format]
           try:
               precision = int(precision)
           except ValueError:
               print >> sys.stderr, 'Error: Precision must be an integer.'
               return 1
       if precision < 0:
           print >> sys.stderr, 'Error: Precision must be nonnegative.'
           return 1
       return_value = 0
       for number in args:
           try:
               number = str2num(number, input_base)
               print num2str(number, output_base, format, precision)
           except (ValueError, TypeError):
               print >> sys.stderr, 'Invalid number: %s' % number
               return_value = 1
   return return_value


if __name__ == '__main__':
   raise SystemExit(_main())
Top
JDozen
Posted: Aug 23 2007, 12:23 PM


Casual Member


Group: Members
Posts: 82
Member No.: 113
Joined: 1-June 07



There should be a fairly simple way of base conversation for EXCEL. I'll bring it in when I'll find it. I think more folks are familiar with EXCEL than with python wink.gif
Top
Dan
Posted: Aug 24 2007, 12:59 AM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



QUOTE (JDozen @ Aug 23 2007, 06:23 AM)
There should be a fairly simple way of base conversation for EXCEL. I'll bring it in when I'll find it. I think more folks are familiar with EXCEL than with python wink.gif

I don't have Excel on my home PC, but OpenOffice has BASE and DECIMAL functions. But they only work for integers.
Top
Dan
Posted: May 5 2012, 02:51 PM


Dozens Disciple


Group: Members
Posts: 1,015
Member No.: 19
Joined: 8-August 05



A new version of baseconv which is 3.x compatible, and uses the new fractions.Fraction class:

CODE
#!/usr/bin/python3

"""Command-line base-conversion utility.

This program converts its arguments from one mathematical base to another.
Floating-point and scientific notation (mant@exp) are supported.

USAGE

  baseconv [-i base] [-o base] [{-e|-f|-g} precision] number ...

OPTIONS

 -i base
    the base in which the arguments are written (default: 10)
 -o base
    the base in which to display the output (default: 10)
 -e precision
    display results in exponential format, e.g. 1.234567@-3
    precision = the number of "decimal places" in the mantissa
 -f precision
    display results in fixed-point format, e.g. 0.001235
    precision = the number of "decimal places"
 -g precision
    display reults in -e or -f format, whichever is shorter
    precision = the number of significant digits
"""

from __future__ import division, print_function, unicode_literals

import getopt
import math
import sys
from fractions import Fraction

DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'


def _atoi(string, base):
  """Convert a string to the corresponding number."""
  return int(string, base)


def _itoa(num, base):
  """Return the string representation of a number in the given base."""

  # to avoid having _itoa(0) == ''
  if num == 0:
      return DIGITS[0]

  # if num is negative, convert the abs and add the sign later
  negative = num < 0
  if negative:
      num = -num

  # build the numeral one digit at a time, from right to left
  digits = []
  while num:
      num, last_digit = divmod(num, base)
      digits.append(DIGITS[last_digit])
  if negative:
      digits.append('-')
  return ''.join(reversed(digits))


def str2num(string, base):
  """Convert a string to its numeric representation."""

  string = ''.join(string.split()) # remove all whitespace

  # Check whether the number is negative
  negative = string.startswith('-')
  if negative:
      string = string[1:]

  # Check whether the number is in scientific notation
  # number = mantissa * base ** exponent
  if '@' in string:
      mantissa, exponent = string.split('@')
      exponent = _atoi(exponent, base)
  else:
      mantissa = string
      exponent = 0

  # Check whether the number contains a radix point
  if '.' in mantissa:
      int_part, frac_part = mantissa.split('.')
      exponent -= len(frac_part)
      mantissa = int_part + frac_part

  mantissa = _atoi(mantissa, base)
  if negative:
      mantissa = -mantissa
  if exponent < 0:
      return Fraction(mantissa, base ** (-exponent))
  else:
      return Fraction(mantissa * base ** exponent)


def _frexp(num, base):
  """Return (mant, exp) such that num == mant * base ** exp"""
  if num == 0:
      return Fraction(0), 0
  mantissa = num
  exponent = 0
  while abs(mantissa) < 1:
      mantissa *= base
      exponent -= 1
  while abs(mantissa) >= base:
      mantissa /= base
      exponent += 1
  return Fraction(mantissa), exponent

def _round(num):
  """Round num to the nearest integer using round-to-even."""
  negative = num < 0
  if negative:
      num = -num
  int_part = int(num)
  frac_part = num - int_part
  if frac_part == Fraction(1, 2):
      int_part += int_part & 1
  elif frac_part > Fraction(1, 2):
      int_part += 1
  if negative:
      int_part = -int_part
  return int_part


def _format_f(num, base, precision):
  """Equivalent of '%.*f' % (num, precision) in the given base."""

  negative = num < 0
  if negative:
      sign = '-'
      num = -num
  else:
      sign = ''

  multiplier = base ** precision
  num *= multiplier
  num = _round(num)
  if precision == 0:
      return _itoa(num, base)
  ipart, fpart = divmod(num, multiplier)
  return '%s%s.%s' % (sign, _itoa(ipart, base),
                     _itoa(fpart, base).zfill(precision))


def _format_e(num, base, precision):
  """Equivalent of '%.*e' % (num, precision) in the given base."""
  mantissa, exponent = _frexp(num, base)
  while True:
      result = '%s@%s' % (_format_f(mantissa, base, precision),
                          _itoa(exponent, base))
      # check to see whether rounding created a denormalized number
      if result.lstrip('-').find('.') > 1:
          mantissa /= base
          exponent += 1
      else:
          return result


def _format_g(num, base, precision):
  """Equivalent of '%.*g' % (num, precision) in the given base."""
  exponent = _frexp(num, base)[1]
  f_format = _format_f(num, base, max(0, precision - exponent - 1))
  e_format = _format_e(num, base, precision - 1)
  if len(e_format) < len(f_format):
      return e_format
  else:
      return f_format


def num2str(num, base, format='g', precision=None):
  """Converts a number to its string representation in the given base."""
  if precision is None:
      precision = int(math.log(2 ** 53, base))
  num = Fraction(num)
  if format == 'f':
      return _format_f(num, base, precision)
  elif format == 'e':
      return _format_e(num, base, precision)
  elif format == 'g':
      return _format_g(num, base, precision)
  else:
      raise ValueError('Unsupported format: %%%s' % format)


def _main(argv=None):
  """Executed when this file is run as a script."""
  if argv is None:
      argv = sys.argv
  opts, args = getopt.getopt(argv[1:], 'e:f:g:i:o:', ['help'])
  opts = dict(opts)
  if '--help' in opts:
      print(__doc__)
  else:
      try:
          input_base = int(opts.get('-i', 10))
          output_base = int(opts.get('-o', 10))
      except ValueError:
          print('Error: Bases must be integers.', file=sys.stderr)
          return 1
      if (input_base < 2 or input_base > 36 or
          output_base < 2 or output_base > 36):
          print('Error: Base must be 2-36.', file=sys.stderr)
          return 1
      format_e = '-e' in opts
      format_f = '-f' in opts
      format_g = '-g' in opts
      precision = None
      if format_e + format_f + format_g > 1:
          print('Error: Only one format can be specified.', file=sys.stderr)
          return 1
      elif format_e:
          format = 'e'
      elif format_f:
          format = 'f'
      elif format_g:
          format = 'g'
      else:
          format = 'g'
          precision = int(math.log(2 ** 53, output_base))
      if precision is None:
          precision = opts['-' + format]
          try:
              precision = int(precision)
          except ValueError:
              print('Error: Precision must be an integer.', file=sys.stderr)
              return 1
      if precision < 0:
          print('Error: Precision must be nonnegative.', file=sys.stderr)
          return 1
      return_value = 0
      for number in args:
          try:
              number = str2num(number, input_base)
              print(num2str(number, output_base, format, precision))
          except (ValueError, TypeError):
              print('Invalid number: %s' % number, file=sys.stderr)
              return_value = 1
  return return_value


if __name__ == '__main__':
  raise SystemExit(_main())

Top
Ged
Posted: Aug 4 2012, 08:29 PM


Casual Member


Group: Members
Posts: 65
Member No.: 16
Joined: 6-August 05



I found a thread that was already on the subject cool.gif

I have a GUI Base Converter written in Java if anyone is interested.

I would like one for my Mobile though sad.gif

But what I thought would be interesting is if anyone knows of any short cut tricks to convert Decimal to Dozenal and vice versa cool.gif I am thinking about numbers one uses often not huge ones.


--------------------
Dozenal numbers: ten_doz.JPG or X for Ten, elf_doz.JPG or E for Eleven said as Elv.

Member of :

DSGB http://www.dozenalsociety.org.uk/
DSA http://www.dozenal.org/
Top
Treisaran
Posted: Aug 4 2012, 09:09 PM


Dozens Disciple


Group: Members
Posts: 855
Member No.: 630
Joined: 14-February 12



QUOTE (Ged)
But what I thought would be interesting is if anyone knows of any short cut tricks to convert Decimal to Dozenal and vice versa cool.gif I am thinking about numbers one uses often not huge ones.


My classification of base conversion difficulty levels puts conversion between decimal and dozenal at the medium-hard level, being bases that are neither exponent relations (easiest) nor divisor relations (medium-easy), yet not coprime (hardest). Consequently, there are anchor points that can facilitate the conversion: decimal and dozenal meet at every decimal 60 = dozenal *50.

Remembering as many multiples of each base as possible will make mental conversion easier. The decimal numbers 12, 144 and 1728 should be memorised, and the dozenal numbers *X, *84 and *6E4, which are powers of one base viewed from the other.

Indeed, it's useful to see how the multiples of each base look in the view of the other. The following table lists the dozenal multiples (1, 2, 3 up to *10 in the first column, then *10, *20, *30 up to *100 in the next column, then the grosses, then the grands) in their decimal forms:

1121441728
2242883456
3364325184
4485766912
5607208640
67286410368
784100812096
896115213824
9108129615552
10120144017280
11132158419008
12144172820736


And this table does the same the other way round (decimal multiples in their dozenal forms):

1X846E4
21814811X8
32621018X0
4342942394
5423582X88
6504203580
75X4X44074
8685684768
9766305260
X846E45954


The more you remember of these tables, the more you'll be able to convert easily in your head. Apropos, I've had to do a mental conversion just this day: I was wondering how the number 5772 (the Anno Mundi count) was in dozenal, so I first used 5760 = 24↑2·10 = *20↑2·X = *400·X = *3400, then added a dozen to give the answer *3410.


--------------------
Conventions as of 18 Apr 11E9:
Dozenal numbers are unmarked, decimal numbers are prefixed with 'đ'. The first three dozenal powers in everyday counting are 'dozen', 'gross' and 'grand'; SDN is used starting from the sixth power ('hexua' and so forth).
Top
dgoodmaniii
Posted: Aug 4 2012, 10:38 PM


Dozens Disciple


Group: Admin
Posts: 1,482
Member No.: 554
Joined: 21-May 09



QUOTE (Ged @ Aug 4 2012, 08:29 PM)
I would like one for my Mobile though sad.gif

Assuming that by "mobile" you mean "mobile phone," what type of mobile phone do you have? It's probably quite trivial to recompile your Java converter for an Android phone. With an iOS phone, though, you'll probably need to rewrite it.


--------------------
All numbers in my posts are dozenal unless stated otherwise.
For ten, I use :A or X; for elv, I use :B or E. For the digital/fractional/radix point, I use the Humphrey point, ";".
TGM for the win!
Dozenal Adventures
Top
Ged
Posted: Aug 4 2012, 10:42 PM


Casual Member


Group: Members
Posts: 65
Member No.: 16
Joined: 6-August 05



I have a Nokia 5230 mobile phone.

Is their a web site that a mobile phone could use for conversions?


--------------------
Dozenal numbers: ten_doz.JPG or X for Ten, elf_doz.JPG or E for Eleven said as Elv.

Member of :

DSGB http://www.dozenalsociety.org.uk/
DSA http://www.dozenal.org/
Top
dgoodmaniii
Posted: Aug 6 2012, 12:52 AM


Dozens Disciple


Group: Admin
Posts: 1,482
Member No.: 554
Joined: 21-May 09



QUOTE (Ged @ Aug 4 2012, 10:42 PM)
I have a Nokia 5230 mobile phone.

Is their a web site that a mobile phone could use for conversions?

Googling tells me that this phone runs Symbian. Since Nokia appears to be more or less killing Symbian in order to further their alliance with Microsoft, and since I don't know of any Java runtime for Symbian, you're probably out of luck unless you learn how to program for Symbian.

But I didn't search the results very deeply; it may be that there's a runtime already laying around somewhere. The only one I found had been canceled.


--------------------
All numbers in my posts are dozenal unless stated otherwise.
For ten, I use :A or X; for elv, I use :B or E. For the digital/fractional/radix point, I use the Humphrey point, ";".
TGM for the win!
Dozenal Adventures
Top
dgoodmaniii
Posted: Aug 6 2012, 12:55 AM


Dozens Disciple


Group: Admin
Posts: 1,482
Member No.: 554
Joined: 21-May 09



QUOTE (Ged @ Aug 4 2012, 10:42 PM)
Is their a web site that a mobile phone could use for conversions?

Many. My favorite is the world's first (allegedly), though it has the downside that it uses the "Bell" characters for ten and elv, and it can't handle exponential notation. But it's quite fast and easy to use, and it works both ways.


--------------------
All numbers in my posts are dozenal unless stated otherwise.
For ten, I use :A or X; for elv, I use :B or E. For the digital/fractional/radix point, I use the Humphrey point, ";".
TGM for the win!
Dozenal Adventures
Top
Ged
Posted: Aug 6 2012, 08:56 AM


Casual Member


Group: Members
Posts: 65
Member No.: 16
Joined: 6-August 05



I tried the World First but it didn't work on my mobile phone.

However I found this one Base Converter and it works OK on the mobile phone.


--------------------
Dozenal numbers: ten_doz.JPG or X for Ten, elf_doz.JPG or E for Eleven said as Elv.

Member of :

DSGB http://www.dozenalsociety.org.uk/
DSA http://www.dozenal.org/
Top
m1n1f1g
Posted: Aug 6 2012, 10:17 PM


Dozens Disciple


Group: Members
Posts: 664
Member No.: 591
Joined: 20-February 11



You could try my converter, which handles any base with any arbitrary digit set. It also handles recurring digital fractions smoothly. However, I've never tested it beyond Chrome and Firefox (maybe Opera, I can't remember).


--------------------
A few little conventions:
- Dozenal integers suffixed with prime (′). This is the uncial point.
- Decimal integers suffixed with middle dot (·). This is the decimal point.

You may see me use * prefix for messages before 11Ɛ7-03-1X, and a whole range of similar radix points. I will often use X and Ɛ for ten_doz.JPG and elf_doz.JPG.

Sometimes, I will imply that an integer is in dozenal, so I won't add any marks to it. You should be able to tell that "10 = 22 * 3" is in dozenal.
Top
0 User(s) are reading this topic (0 Guests and 0 Anonymous Users)
0 Members:
« Next Oldest | Applications and appliances | Next Newest »
DealsFor.me - The best sales, coupons, and discounts for you

Topic Options



Hosted for free by InvisionFree* (Terms of Use: Updated 2/10/2010) | Powered by Invision Power Board v1.3 Final © 2003 IPS, Inc.
Page creation time: 0.5126 seconds | Archive