##################################################### Sample Solution to Lab2 Problems #####################################################
Problem ->
1. Older computers used Binary Coded Decimals (BCD) to represent integers. In this each digit is represented by using 4 bits. So 0 is 0000, 1 is 0001, 2 is 0010, ... 9 is 1001. The remaining 4 bit patterns, namely 1010 onwards are illegal. So 32 bits can store upto 8 digits. To represent a negative number the sign is also encoded using 4 bits. However, we are interested only in positive BCD numbers. For example assuming we have 32 bits the number 123 will be represented as (0000) 5 times followed by 000100100011.
Define a class BCD with a single constructor which takes an int argument and creates its BCD equivalent. Write methods for adding, subtracting, multiplying and dividing BCD numbers. Also, write methods to check for <, > and == between two BCD numbers. [15]
Solution ->
public class BCD{
static final int NO_OF_NYBBLES = 8; int[] nybble = new int[NO_OF_NYBBLES];
//Constructors public BCD(){ int i; for( i = 0; i < NO_OF_NYBBLES; i++ ) nybble[i] = 0; }
public BCD(int i){ int j; int val = i; for( j = NO_OF_NYBBLES - 1; j >= 0; j-- ){ nybble[j] = val % 10; val = val / 10; } }
public BCD(BCD b){ int i; for( i = 0; i < NO_OF_NYBBLES; i++ ) nybble[i] = b.getNthNybble(i); }
//Get the BCD digit at nth position
public int getNthNybble(int n){ return nybble[n]; }
//Set BCD digit at nth position
public void setNthNybble(int n, int val){ nybble[n] = val; }
//Convert BCD from internal representation to String
public String toString(){ String s = new String(""); int i; for( i = 0; i < NO_OF_NYBBLES; i++ ){ Integer iNybble = new Integer(nybble[i]); s += iNybble.toString(); } return s; }
//Convert BCD from internal representation to integer
public int toInteger(){ int i, factor = 1, sum = 0;
if ( nybble[0] == 15 ) return -1;
for( i = NO_OF_NYBBLES - 1; i >= 0; i--){ sum += nybble[i] * factor; factor = factor * 10; } return sum; }
//Make a copy of this BCD object
public BCD copy(){ BCD bcdcopy = new BCD(0); int i; for( i = 0; i < NO_OF_NYBBLES; i++ ) bcdcopy.setNthNybble(i, nybble[i]); return bcdcopy; }
// Add 2 BCD nos and return BCD sum
public BCD add(BCD bcd2){ BCD bcdsum = new BCD(0); int i, tempsum, carry = 0; static final int MASK = 15;
for( i = NO_OF_NYBBLES - 1; i >= 0; i-- ){ tempsum = nybble[i] + bcd2.getNthNybble(i) + carry;
/*If sum of 2 BCD digits is > 9, need to add 6 to it to bring it back to correct sum. In this case, there's a carry to next 4 bits*/
if ( tempsum > 9 ){ carry = 1; tempsum = (tempsum + 6) & MASK; } else carry = 0; bcdsum.setNthNybble(i, tempsum); } return bcdsum; }
// Subtract 2 BCD nos and return difference
public BCD sub(BCD bcd2){ static final int MASK = 16; BCD bcd1 = new BCD(0); BCD bcddiff = new BCD(0); int bcd1ipos, bcd2ipos; int i, borrow = 0, tempdiff;
bcd1 = this.copy();
//-ve BCD number is represented by setting nybble of MSD in BCD to all 1's
if ( bcd1.lessthan(bcd2) ){ bcddiff.setNthNybble(0, 15); return bcddiff; }
for( i = NO_OF_NYBBLES - 1; i >= 0; i-- ){ bcd1ipos = bcd1.getNthNybble(i); bcd2ipos = bcd2.getNthNybble(i);
/*If minuend digit < subtrahend digit, borrow 1 from next higher BCD digit and subtract 6 from result*/
if ( bcd1ipos >= (bcd2ipos + borrow) ){ tempdiff = bcd1ipos - bcd2ipos - borrow; borrow = 0; } else{ bcd1ipos = bcd1ipos | MASK; tempdiff = bcd1ipos - bcd2ipos - 6 - borrow; borrow = 1; } bcddiff.setNthNybble(i, tempdiff); } return bcddiff; }
// Multiply 2 BCD nos and return their product
public BCD mul(BCD bcd2){ BCD bcdprod = new BCD(0); BCD bcd1 = new BCD(0); int i1, i2, index;
bcd1 = this.copy();
i1 = bcd1.toInteger(); i2 = bcd2.toInteger();
/* Adding multiplicand to itself multiplier number of times Simple logic but inefficient due to large number of method calls */ if ( i1 < i2 ) for( index = 0; index < i1; index++ ) bcdprod = bcdprod.add(bcd2); else for( index = 0; index < i2; index++ ) bcdprod = bcdprod.add(bcd1);
return bcdprod; }
// Divide 2 BCD nos and return their quotient
public BCD div(BCD bcd2){ BCD bcddiv = new BCD(this); BCD bcdquot; int plicand, quot = -1;
/* Subtracting dividend by divisor till convergence Simple logic but inefficient due to large number of method calls */ do{ quot++; bcddiv = bcddiv.sub(bcd2); plicand = bcddiv.toInteger(); }while ( plicand >= 0);
bcdquot = new BCD(quot); return bcdquot; }
// Divide 2 BCD nos and return the remainder
public BCD mod(BCD bcd2){ BCD bcdrem = new BCD(this); int plicand;
/* Subtracting dividend by divisor till convergence Simple logic but inefficient due to large number of method calls */ do{ if ( bcdrem.lessthan(bcd2) ) return bcdrem;
bcdrem = bcdrem.sub(bcd2); plicand = bcdrem.toInteger(); }while ( plicand >= 0);
return bcdrem; }
//Return true if this BCD < bcd2 and false otherwise
public boolean lessthan(BCD bcd2){ int i, bcd2ipos;
for(i = 0; i < NO_OF_NYBBLES; i++){ bcd2ipos = bcd2.getNthNybble(i); if ( nybble[i] < bcd2ipos ) return true; else if ( nybble[i] > bcd2ipos ) return false; } return false; }
//Return true if this BCD > bcd2 and false otherwise
public boolean greaterthan(BCD bcd2){ int i, bcd2ipos;
for(i = 0; i < NO_OF_NYBBLES; i++){ bcd2ipos = bcd2.getNthNybble(i); if ( nybble[i] > bcd2ipos ) return true; else if ( nybble[i] < bcd2ipos ) return false; } return false; }
//Return true if this BCD equals bcd2 and false otherwise
public boolean equalto(BCD bcd2){ int i, bcd2ipos;
for(i = 0; i < NO_OF_NYBBLES; i++){ bcd2ipos = bcd2.getNthNybble(i); if ( nybble[i] != bcd2ipos ) return false; } return true; } }
***********************************************************************************************
problem ->
2. Write a class Convert with static methods as follows: a) takes 4 arguments representing miles, yards, feet and inches and converts them into kilometers, meters and centimeters. b) takes an argument representing degrees Farenheit and converts it to degrees centrigrade. c) a kilobyte is interpreted in two ways: some times it is 1000 bytes (actually correct), but often (and traditionally) it is 210 which is 1024. Similar discrepancies arise for mega, giga, tera and peta (each is 1000 (or 210 ) times the previous one). The function should take the 103 (standard kilo) and give the equivalent value using 210 as a kilo for all the above.
[10]
Solution ->
public class Convert{
//Convert from miles, yards, feet and inches to km, meters and cm
public static Metric fpstometric(int m, int y, int f, double i){ final int INCHES_PER_FEET = 12; final int INCHES_PER_YARD = 3 * INCHES_PER_FEET; final int INCHES_PER_MILE = 1760* INCHES_PER_YARD; final double CMS_PER_INCH = 2.54; final int CMS_PER_METER = 100; final int CMS_PER_KM = 1000 * CMS_PER_METER;
Metric metric = new Metric(); double totinches = 0; double totcm = 0; int km, mt;
//Converting input arguements into a single unit - inches totinches = m * INCHES_PER_MILE + y * INCHES_PER_YARD + f * INCHES_PER_FEET + i;
totcm = totinches * CMS_PER_INCH; if ( (int)totcm > CMS_PER_KM ){ //Set Km km = (int) totcm / CMS_PER_KM; metric.setKm(km); totcm = (int) totcm % CMS_PER_KM; }
if ( (int)totcm > CMS_PER_METER ){ //Set meters mt = (int)totcm / CMS_PER_METER; metric.setMt(mt); totcm = (int) totcm % CMS_PER_METER; }
metric.setCm(totcm); return metric; }
//Convert temperature in fahren-heit to degree celsius
public static double fahren_to_centi(double f){ double centi = 0.0; centi = 5.0 * (f - 32.0) / 9.0; return centi; }
//Given an input in Standard Kilo units, converts it into traditional kilo units
public static double std_to_trad_kilo(double stdval, char wt){ final double STDKILO = 1.0E3; final double STDMEGA = 1.0E3 * STDKILO; final double STDGIGA = 1.0E3 * STDMEGA; final double STDTERA = 1.0E3 * STDGIGA; final double STDPETA = 1.0E3 * STDTERA;
final double STDKILO_PER_TRADKILO = 1.024E3; final double STDMEGA_PER_TRADMEGA = 1.024E3 * STDKILO_PER_TRADKILO; final double STDGIGA_PER_TRADGIGA = 1.024E3 * STDMEGA_PER_TRADMEGA; final double STDTERA_PER_TRADTERA = 1.024E3 * STDGIGA_PER_TRADGIGA; final double STDPETA_PER_TRADPETA = 1.024E3 * STDTERA_PER_TRADTERA;
double tradval = 0.0; switch(wt){ case 'k' : case 'K' : tradval = (stdval / STDKILO_PER_TRADKILO) * STDKILO; break; case 'm' : case 'M' : tradval = (stdval / STDMEGA_PER_TRADMEGA) * STDMEGA; break; case 'g' : case 'G' : tradval = (stdval / STDGIGA_PER_TRADGIGA) * STDGIGA; break; case 't' : case 'T' : tradval = (stdval / STDTERA_PER_TRADTERA) * STDTERA; break; case 'p' : case 'P' : tradval = (stdval / STDPETA_PER_TRADPETA) * STDPETA; break; default: System.out.println("Error:Unknown weight type(Use k-kilo, m-mega, g-giga, t-tera, p-peta)"); break; } return tradval; }
/* public static void main(String args[]){ Metric m = new Metric(); double centi, val;
m = fpstometric(4, 3, 8, 12.0); System.out.println("Km = " + m.getKm() + "\tMt = " + m.getMt() +"\tCm = " + m.getCm());
centi = fahren_to_centi(104); System.out.println(104 + " degree Fahr = " + centi + " degree Celsius");
val = std_to_trad_kilo(102434784, 'p'); System.out.println("102434784 std peta= " + val + " trad units"); } */
}
public class Metric{
private int kilometers; private int meters; private double centimeters;
public Metric(){ kilometers = 0; meters = 0; centimeters = 0.0; }
public Metric(int cm){ kilometers = 0; meters = 0; centimeters = cm; }
public Metric(int cm, int mt){ kilometers = 0; meters = mt; centimeters = cm; }
public Metric(double cm, int mt, int km){ kilometers = km; meters = mt; centimeters = cm; }
public double getCm(){ return centimeters; }
public void setCm(double cm){ centimeters = cm; }
public int getMt(){ return meters; }
public void setMt(int mt){ meters = mt; }
public int getKm(){ return kilometers; }
public void setKm(int km){ kilometers = km; } }