| 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()) |
| CODE |
| ~$ baseconv -o12 123.456 A3.557B74854619 |
| CODE |
| ~$ baseconv -o12 -f2 123.456 A3.56 |
| CODE |
| ~$ baseconv -o16 6.02214199@23 7.F8618DE5AED9@13 |
| CODE |
| ~$ baseconv -i23 -o12 -g36 0.1 0.0631694842106316948421063169484210632 |
| 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: |
| QUOTE (Twinbee @ Aug 12 2005, 04:27 PM) |
| Dan, if you have time, make it into an exe and give it a GUI :) |
| QUOTE (Twinbee @ Aug 12 2005, 11:27 AM) |
| Dan, if you have time, make it into an exe and give it a GUI :) |
| QUOTE (finlay @ Aug 18 2005, 12:25 PM) |
| OK it's not working. Some syntax error? Not sure if it's yours or mine. |
| 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 |
| QUOTE (Ged @ Jul 22 2007, 09:16 AM) |
| I had the same problem with Python. |
| 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()) |
| 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 ;) |