Java  1.0
baseConverter.java
Go to the documentation of this file.
1 import java.util.Arrays;
2 import java.text.DecimalFormat;
3 import java.text.DecimalFormatSymbols;
4 
64 public class baseConverter {
66  static private final char decimalPoint = DecimalFormatSymbols.getInstance().getDecimalSeparator();
67 
69  static private final int WORD_LEN = Integer.SIZE;
70 
72  static private final int EXPO_LEN = 8;
73 
75  static private final int FRAC_LEN = 23;
76 
78  static private final int EXPO_MAG = 127;
79 /*
81  static private final int WORD_LEN = Long.SIZE;
82 
84  static private final int EXPO_LEN = 11;
85 
87  static private final int FRAC_LEN = 52;
88 
90  static private final int EXPO_MAG = 1023;
91 */
92 
98  public static void main(String[] args) {
99  int n = 0, base = 2;
100  double f = 0;
101  if (args.length > 2) {
102  try {
103  n = Integer.parseInt(args[0]);
104  f = Double.parseDouble(args[1]);
105  base = Integer.parseInt(args[2]);
106  } catch (NumberFormatException e) {
107  System.err.println("Arguments: decimal integer, decimal float and base");
108  System.exit(1);
109  }
110  }
111  baseConverter bc = new baseConverter();
112 
113  System.out.println ( String.format ("Size of long = %d ", bc.getLongSize()) );
114  System.out.println ( String.format ("%d * %d = %d ", n, base, bc.Product(n,base)) );
115  String ns = bc.itoa ( n, base );
116  System.out.println ( String.format ("%d in base 10 = %s in base %d", n, ns, base) );
117  System.out.println ( String.format ("%s in base %d = %s in base 10", ns, base, bc.atoi ( ns, base )) );
118  String nsf = bc.ftoa ( f, base );
119  System.out.println ( String.format ("%e in base 10 = %s in base %d", f, nsf, base) );
120  System.out.println ( String.format ("%s in base %d = %s in base 10", nsf, base, bc.atof ( nsf, base )) );
121  String nsIEEE754 = bc.ftoIEEE754 ( f );
122  System.out.println ( String.format ("%s in base %d = %s in IEEE754", nsf, base, nsIEEE754) );
123  System.out.println ( String.format ("%s in IEEE754 = %s in base 10", nsIEEE754, bc.IEEE754tof ( nsIEEE754 )) );
124  System.out.print ( String.format ("%d = ", n) ); bc.printBits ( n );
125  if ( n < 0 ) {
126  System.out.print ( String.format ("(Negative numbers are represented in two's complement)\n") );
127  System.out.print ( String.format ( "~%d+1 = ", -n ) );
128  bc.printBits ( ~-n+1 );
129  }
130  System.out.println ();
131  System.out.print ( String.format ( "Magnitude (%d) = %d\n", n, bc.getMagnitude(n) ) );
132  System.out.println ( String.format ("Number of bits of (%d) = ", n) + bc.getNumberOfBits ( n ) );
133  long k;
134  System.out.print ( String.format ("%d reversed = ", n) ); bc.printBits ( k=bc.reverseBits(n) );
135  System.out.print ( String.format ( " = %d\n", k ) );
136  System.out.print ( String.format ( "Magnitude (%d reversed) = %d\n", n, bc.getMagnitude(k) ) );
137  System.out.println ( String.format ("Number of bits of (%d reversed) = ", n) + bc.getNumberOfBits ( k ) );
138  System.out.println ( String.format ("Power: 2**-4 = %f", bc.pow ( 2,-4 ) ) );
139  System.out.println ( String.format ("Power: 2**3 = %f", bc.pow ( 2,3 ) ) );
140  bc.printAsciiTable();
141  System.out.println ( String.format ("modf: (%e,%e)", modf(f)[0], modf(f)[1]) );
142  System.out.println ( String.format ("frac: (%e,%e)", inte(f), frac(f)) );
143  }
144 
151  public static int Product (int a, int b) {
152  int p = 0;
153  while (b != 0) {
154  if ((b & 1) == 1)
155  p += a;
156  a <<= 1;
157  b >>>= 1;
158  }
159  return p;
160 }
161 
166  public static void printAsciiTable ( ) {
167  for ( int x = 32; x < 127; ++x ) {
168  System.out.print ( String.format ( "%03d = %c ", x, (char) x ) );
169  if ( (x-31)%10 == 0 ) System.out.println ( );
170  }
171  System.out.println ( );
172  }
173 
180  public static long reverseBits(long x) {
181  long h = 0;
182 
183  while (x!=0) {
184  h = (h << 1) | (x & 1);
185  x >>>= 1;
186  }
187 
188  return h;
189  }
190 
198  public static double pow(long x, long p) {
199  long pw = ipow(x, Math.abs(p));
200  return p >= 0 ? pw : 1.0/pw;
201  }
202 
210  public static long ipow(long x, long p) {
211  if ( p <= 0 )
212  return 1;
213  else if ( p%2 == 0 ) {
214  long pw = ipow (x, p/2);
215  return pw*pw;
216  }
217  else {
218  long pw = ipow (x,(p-1)/2);
219  return x*pw*pw;
220  }
221  }
222 
229  public static void printBits (long n) {
230  // do not print zeros on the left
231  if (n == 0 || n == 1) {
232  System.out.print ( n );
233  }
234  else {
235  // >>> is the logical right shift, necessary because of the lack of an
236  // unsigned type in Java.
237  printBits (n >>> 1);
238  System.out.print ( n & 1 );
239  }
240  }
241 
248  public static int getMagnitude ( long n ) {
249  int d = 0;
250  while (n!=0) {
251  n /= 10;
252  ++d;
253  }
254  return d;
255  }
256 
263  public static int getNumberOfBits ( long n ) {
264  int c = 0;
265  while (n!=0) {
266  n >>>= 1; // logical shift
267  ++c;
268  }
269  return c;
270  }
271 
277  public static int getLongSize ( ) {
278  long a = 1;
279  int c = 0;
280  while (a!=0) {
281  a <<= 1;
282  ++c;
283  }
284  return c;
285  }
286 
299  public static String itoa ( int num, int base ) {
300  String str = "";
301  if ( num == 0 ) return "0";
302  if ( base < 2 || base > 36 ) return str; // starting at 10 and using 26 letters equals 36
303 
304  int n = Math.abs(num);
305  int nb;
306 
307  while ( n != 0 ) {
308  nb = n%base;
309  if ( base > 10 && nb > 9 )
310  str = (char)(nb-10 + 'a') + str;
311  else
312  str = nb + str;
313  n /= base;
314  }
315 
316  if ( num < 0 ) str = '-' + str;
317  return str;
318  }
319 
329  public static String fftoa ( double num, int base ) {
330  String str = "";
331  if ( num == 0 ) return "0";
332  if ( base < 2 || base > 36 ) return str; // starting at 10 and using 26 letters equals 36
333 
334  double n = Math.abs(num);
335 
336  while ( n != 0 ) {
337  int nb = (int)modf(n%base)[0];
338  if ( base > 10 && nb > 9 )
339  str = (char)(nb-10 + 'a') + str;
340  else
341  str = (char)(nb+'0') + str;
342  n = modf(n/base)[0];
343  }
344 
345  if ( num < 0 ) str = '-' + str;
346  return str;
347  }
348 
355  public static String trimTrailingZeros ( String str ) {
356  int i;
357  for ( i = str.length()-1; i >= 0; i-- ) {
358  if (str.charAt(i) != '0' || str.charAt(i) == decimalPoint)
359  break;
360  }
361  if (str.charAt(i) == decimalPoint) i += 1;
362  return str.substring(0,i+1);
363  }
364 
372  public static String normalize ( String str ) {
373  int point = str.indexOf(decimalPoint);
374  StringBuilder str2 = new StringBuilder();
375  if ( point >= 2 ) { // more than two digits before the decimal point (a positive expoent)
376  str2.append (str.charAt(0)+decimalPoint);
377  str2.append (str,1,point);
378  str2.append (str,point+1,str.length());
379  str2.replace(0,str2.length(),trimTrailingZeros(str2.toString()));
380  str2.append ("E");
381  str2.append (itoa(point-1,10));
382  str = str2.toString();
383  } else {
384  int i;
385  for ( i = 0; i < str.length(); ++i ) {
386  if ( str.charAt(i) != '0' && str.charAt(i) != decimalPoint )
387  break;
388  }
389  if ( i >= 2 && i < str.length() ) { // a number of the form 0. (a negative expoent)
390  i = Math.min (i,EXPO_MAG); // expo should be in the range [-126..127]
391  str2.append (str.charAt(i)+decimalPoint);
392  str2.append (str,i+1,str.length());
393  if ( str2.charAt(str2.length()-1) == decimalPoint )
394  str2.append ('0'); // for not having a number ending just with a point
395  str2.replace(0,str2.length(),trimTrailingZeros(str2.toString()));
396  str2.append ("E");
397  str2.append (itoa(-i+1,10));
398  str = str2.toString();
399  }
400  }
401  return str;
402 }
403 
416  public static String ftoa ( double num, int base ) {
417  String str = "";
418  if ( num == 0 ) return "0";
419  if ( base < 2 || base > 36 ) return str; // starting at 10 and using 26 letters equals 36
420 
421  double n = Math.abs(num);
422  double nf = modf(n)[1]; // fractional part
423 
424  str = fftoa ( modf(n)[0], base ) + decimalPoint;
425 
426  int cnt = 0; // to avoid an infinite loop in case of a repeating (recurring) decimal
427  while ( nf > 0.0 && cnt++ < EXPO_MAG+FRAC_LEN ) {
428  nf *= base;
429  int ni = (int)nf;
430  if ( ni > 9 )
431  str += (char)((ni-10)+'a');
432  else
433  str += (char)(ni+'0');
434  nf = modf(nf)[1];
435  }
436 
437  str = normalize(str);
438 
439  if ( num < 0 )
440  str = '-' + str;
441  return str;
442  }
443 
450  public static String zero (int len) {
451  char[] repeat = new char[len];
452  Arrays.fill(repeat, '0');
453  return new String(repeat);
454  }
455 
464  public static String ftoIEEE754 ( double num ) {
465  int base = 2;
466 
467  if (num == 0)
468  return zero(FRAC_LEN+EXPO_LEN+1);
469 
470  String str = ftoa ( num, base );
471 
472  String[] parts = str.split("E");
473  int expo = 0;
474  if ( parts.length > 1 ) {
475  expo = atoi(parts[1],10); // the expoent is in base 10
476  expo = Math.min(Math.max(expo,-EXPO_MAG),EXPO_MAG);
477  }
478 
479  String expoent = itoa(expo+EXPO_MAG,base);
480  if ( str.charAt(0) == '0' || (str.charAt(0) == '-' && str.charAt(1) == '0') ) // a denormalized number
481  expoent = "0";
482  if ( expoent.length() < EXPO_LEN ) {
483  expoent = zero(EXPO_LEN).substring(expoent.length()) + expoent;
484  }
485  else
486  expoent = expoent.substring(0,EXPO_LEN);
487 
488  String mantissa = parts[0].substring(parts[0].indexOf(decimalPoint)+1,parts[0].length());
489  String signal = (num < 0) ? "1" : "0";
490  if ( mantissa.length() < FRAC_LEN ) {
491  mantissa += zero(FRAC_LEN).substring(mantissa.length());
492  }
493  else
494  mantissa = mantissa.substring(0,FRAC_LEN);
495 
496  return signal+expoent+mantissa;
497  }
498 
507  public static double IEEE754tof ( String num ) {
508  if (num.equals(zero(FRAC_LEN+EXPO_LEN+1)))
509  return 0;
510  int signal = num.charAt(0) == '1' ? -1 : 1;
511  int expoent = atoi(num.substring(1,EXPO_LEN+1),2)-EXPO_MAG;
512  double mantissa;
513  if (expoent == -EXPO_MAG) { // denormalize the number
514  mantissa = atof("0"+decimalPoint+num.substring(EXPO_LEN+1,EXPO_LEN+1+FRAC_LEN),2);
515  expoent += 1;
516  } else
517  mantissa = atof("1"+decimalPoint+num.substring(EXPO_LEN+1,EXPO_LEN+1+FRAC_LEN),2);
518  return signal * mantissa * Math.pow(2,expoent);
519  }
520 
528  public static int atoi ( String num, int base ) {
529  int n = 0;
530  int len = num.length();
531  if ( base < 2 || base > 36 || len < 1 ) return n; // starting at 10 and using 26 letters equals 36
532 
533  int p = 1;
534  char c;
535  int j;
536  for (int i = len-1; i>=0; i--){
537  c = num.charAt(i);
538  if ( base > 10 && c >= 'a' && c <= 'a'+base-11 ) {
539  c -= 'a';
540  j = (int)c + 10;
541  }
542  else if ( c >= '0' && c <= '0'+Math.min(base,10)-1 ) {
543  c -= '0';
544  j = (int)c;
545  } else j = 0;
546 
547  n += p*j;
548  p *= base;
549  }
550  return num.charAt(0)=='-'?-n:n;
551  }
552 
560  public static double atof ( String num, int base ) {
561  double n = 0;
562  int len = num.length();
563 
564  if ( base < 2 || base > 36 || len < 1 ) return n; // starting at 10 and using 26 letters equals 36
565 
566  String[] parts = num.split("E");
567  num = parts[0];
568  len = num.length();
569  int pt = num.indexOf(decimalPoint);
570  int point = len - Math.max(pt,0) - 1; // number of digits after the point
571  if ( parts.length > 1 ) {
572  point -= atoi(parts[1],10); // add the expoent
573  }
574 
575  if ( pt == -1 ) { // no point found
576  num += decimalPoint+"0";
577  point = 1; // number of digits after the point
578  len+=2;
579  }
580 
581  double p = Math.pow(base,-point);
582  char c;
583  int j;
584  for (int i = len-1; i>=0; i--){
585  c = num.charAt(i);
586  if ( base > 10 && c >= 'a' && c <= 'a'+base-11 ) {
587  c -= 'a';
588  j = (int)c + 10;
589  }
590  else if ( c >= '0' && c <= '0'+Math.min(base,10)-1 ) {
591  c -= '0';
592  j = (int)c;
593  } else continue;
594 
595  n += p*j;
596  p *= base;
597  }
598  return num.charAt(0)=='-'?-n:n;
599  }
600 
607  private static double frac(double d) {
608  return d-inte(d);
609  }
610 
617  private static double inte(double d) {
618  return d > 0 ? Math.floor(d) : Math.ceil(d);
619  }
620 
629  private static double[] modf(double d) {
630  String num = Double.toString(d);
631  double[] arr = new double[2];
632  String[] parts = num.split("E");
633  if ( parts.length > 1 ) {
634  int expo = Integer.valueOf ( parts[1] );
635  if ( expo > 0 ) {
636  int pt = parts[0].indexOf(decimalPoint);
637  int len = parts[0].length();
638  int nc = pt+1+expo;
639  String number = parts[0].substring(0,pt);
640  number += parts[0].substring(pt+1,Math.min(nc,len));
641  String frac="0"+decimalPoint;
642  if ( nc < len ) {
643  frac += parts[0].substring( nc, len );
644  if ( d < 0 ) frac = '-'+frac;
645  }
646  else
647  number += zero(nc-len);
648  arr[0] = Double.parseDouble(number);
649  arr[1] = Double.parseDouble(frac);
650  } else {
651  arr[0] = 0;
652  arr[1] = Double.parseDouble(num);
653  }
654  } else {
655  parts = num.split("\\"+decimalPoint);
656  if ( parts.length > 1 ) {
657  parts[1] = "0"+decimalPoint+parts[1];
658  if ( d < 0 ) parts[1] = '-'+parts[1];
659  }
660  for ( int i = 0; i < parts.length; ++i )
661  arr[i] = Double.parseDouble(parts[i]);
662  }
663  return arr;
664  }
665 }
baseConverter.ipow
static long ipow(long x, long p)
Efficiently calculate integer positive powers by repeated squaring.
Definition: baseConverter.java:210
baseConverter.trimTrailingZeros
static String trimTrailingZeros(String str)
Trim trailing zeros at the end of a string.
Definition: baseConverter.java:355
baseConverter
Class for converting between different numerical bases.
Definition: baseConverter.java:64
baseConverter.atoi
static int atoi(String num, int base)
Converts a String, representing a number in a given base, to decimal.
Definition: baseConverter.java:528
baseConverter.EXPO_MAG
static final int EXPO_MAG
Magnitude for the IEEE 754 expoent.
Definition: baseConverter.java:78
baseConverter.ftoIEEE754
static String ftoIEEE754(double num)
Converts a float value to a string representing the number in the IEEE 754 standard:
Definition: baseConverter.java:464
baseConverter.decimalPoint
static final char decimalPoint
Decimal point separator.
Definition: baseConverter.java:66
baseConverter.inte
static double inte(double d)
Returns the integer part of a double.
Definition: baseConverter.java:617
baseConverter.FRAC_LEN
static final int FRAC_LEN
Number of bits for the IEEE 754 fraction.
Definition: baseConverter.java:75
baseConverter.modf
static double[] modf(double d)
Extracts the integer and fractional parts of a double.
Definition: baseConverter.java:629
baseConverter.IEEE754tof
static double IEEE754tof(String num)
Converts a string representing a number in the IEEE 754 standard to float:
Definition: baseConverter.java:507
baseConverter.ftoa
static String ftoa(double num, int base)
Converts a float value to a string using the specified base and returns it.
Definition: baseConverter.java:416
baseConverter.getLongSize
static int getLongSize()
Gets the size of a long.
Definition: baseConverter.java:277
baseConverter.getNumberOfBits
static int getNumberOfBits(long n)
Gets the number of binary digits of a long.
Definition: baseConverter.java:263
baseConverter.main
static void main(String[] args)
main function for testing.
Definition: baseConverter.java:98
baseConverter.Product
static int Product(int a, int b)
Multiplies two integers by using only the + operation.
Definition: baseConverter.java:151
baseConverter.atof
static double atof(String num, int base)
Converts a String, representing a number in a given base, to a float point decimal.
Definition: baseConverter.java:560
baseConverter.printAsciiTable
static void printAsciiTable()
Prints the ASCII table from ' ' (32) to '~' (126).
Definition: baseConverter.java:166
baseConverter.getMagnitude
static int getMagnitude(long n)
Gets the number of decimal digits of a long.
Definition: baseConverter.java:248
baseConverter.printBits
static void printBits(long n)
Prints the binary representation of a long.
Definition: baseConverter.java:229
baseConverter.WORD_LEN
static final int WORD_LEN
Number of bits for the IEEE 754 word.
Definition: baseConverter.java:69
baseConverter.frac
static double frac(double d)
Returns the fractional part of a double.
Definition: baseConverter.java:607
baseConverter.pow
static double pow(long x, long p)
Efficiently calculate integer powers by repeated squaring.
Definition: baseConverter.java:198
baseConverter.EXPO_LEN
static final int EXPO_LEN
Number of bits for the IEEE 754 expoent.
Definition: baseConverter.java:72
baseConverter.itoa
static String itoa(int num, int base)
Converts an integer value to a string using the specified base and returns it.
Definition: baseConverter.java:299
baseConverter.fftoa
static String fftoa(double num, int base)
Similar to function itoa, but accepts a double as argument for being able do deal with huge numbers.
Definition: baseConverter.java:329
baseConverter.zero
static String zero(int len)
Returns a string, of a given size, filled with zeroes.
Definition: baseConverter.java:450
baseConverter.reverseBits
static long reverseBits(long x)
Reverses the bits of a long.
Definition: baseConverter.java:180
baseConverter.normalize
static String normalize(String str)
Converts a string representing a float point number to a scientifc notation of the form: x....
Definition: baseConverter.java:372