Introduction to Java

Written by Jan Tobochnik (jant@kzoo.edu))
see original at Kalamazoo U.

Java is a multiplatform object oriented programming language that can be used to create applications or applets. Applications are programs that perform the same functions as those written in other programming languages. Applets are programs that are embedded in a Web page and thus can be accessed over the Internet. Java has a built in application programming interface(API) that works under any operating system. When a program is compiled, a byte code is produced which can be read and executed by any software that can run Java.

Much of the syntax of Java is the same as C and C++. One big difference is that Java does not have pointers. However, the biggest difference is that you must write object oriented code in Java. Procedural pieces of code can only be embedded in objects. In this tutorial we assume you have some familiarity with a programming language. Some familiarity with the syntax of C or C++ will also be useful.

Application Applet GUI Application GUI Applet
Events Animation File input and output Ising Model Templates
Below we show a simple Java application which multiplies two numbers and prints their product. This program is the Java version of Program product in Chapter 2 of Gould & Tobochnik.

Application

class ExampleApplication{
     public static void main( String args[] ) {
       double m, a, force;
       m = 2.0;                       // mass in kilograms
       a = 4.0;                       // acceleration in mks units
       force = m*a;                   // force in newtons
       System.out.println(force);
 }
}
The features of the Java application included in the above program include:

The structure of an applet is slightly different than that of an application. Below we show the same program, but written as an applet.

Applet

import java.awt.*; 
import java.applet.Applet;

public class ExampleApplet extends Applet{
   public void paint( Graphics g ) {
     double m, a, force;
     m = 2.0;                       // mass in kilograms
     a = 4.0;                       // acceleration in mks units
     force = m*a;                   // force in newtons
     g.drawString(String.valueOf(force), 30, 30 );
 }
}
The features of the Java applet that are different than the application are:

Applets are run by web pages. Below we show a simple HTML document which could be used to run the above applet. Note that before the applet can be run the program must be translated into byte code which is placed in the file ExampleApplet.class. The dimensions of the window where the applet will appear are defined in the web page. The web page also allows the user to see the source code for the applet.

<HTML>
<HEAD>
<TITLE>Example Applet</TITLE>
</HEAD>
<HR>
<BODY
<APPLET code="ExampleApplet.class" width=200 height=200>
</APPLET>
<hr>
<a href="ExampleApplet.java">The source.</a>
</BODY>
</HTML>

The main advantage of Java for our purposes is the easy to use graphical user interface(GUI) that comes with the language and that is platform independent. The application below shows how to set up your own interface and one way to input and output your results.

 import java.awt.*;
 
 class GuiApplication {

	public static void main( String args[] ) {
	
	  MyFrame frame = new MyFrame();
	  frame.setTitle("Input Example");
	  frame.resize(500,300);
	  frame.init();
	  frame.show();
	 }
 }
 class MyFrame extends Frame {
    double m = 0;  // mass
    TextField mText,fText;  // textfield to enter mass and output force
    Label mLabel, fLabel;  // label for mass and force textfield
    
    public void init() {
       setLayout(null);   // don't use deffault layout
       setBackground (Color.lightGray);
       mText = new TextField("");   // field to enter mass value
       mText.reshape(20,20,50,20);  // locate at 20,20; 50 pixels wide and 20 pixels high
       add(mText);   // add field to window
       mLabel = new Label("mass");
       mLabel.reshape(20,40,50,20);  //locate label below textfield
       add(mLabel);  //add label to window
       fText = new TextField("");   // field to output force value
       fText.reshape(80,20,50,20);  // locate at 80,20; 50 pixels wide and 20 pixels high
       add(fText);   // add field to window
       fLabel = new Label("force");
       fLabel.reshape(80,40,50,20);  //locate label below textfield
       add(fLabel);  //add label to window
     }
     
    public void product() {
       double a = 5.0,force;
       force = m*a;      // m is found from handle event routine below
       fText.setText(String.valueOf(force));
     }
       
    public boolean handleEvent(Event e) {
       Rectangle mRect = mText.bounds();  // boundary of mass textfield
       if ((e.x == mRect.x) && (e.y == mRect.y))  // text entered in mass textfield
        {
          Double M = new Double(mText.getText ());  // convert string to Double object
          m = M.doubleValue();   // get value of mass from Double object
          product(); 
          return (true);
         }
       else if (e.id == Event.WINDOW_DESTROY) // only needed for application
        {
          System.exit(0);
          return(true);
        }
       return super.handleEvent(e);  // take care of all other events
     }
}

The features of the Java application included in the above program include:

The above application can be rewritten as an applet, as shown below.

 import java.awt.*;
 import java.applet.*;
 
 public class GuiApplet extends Applet{
	   double m = 0;  // mass
    TextField mText,fText;  // textfield to enter mass and output force
    Label mLabel, fLabel;  // label for mass and force textfield
    
    public void init(){
       setLayout(null);   // don't use deffault layout
       setBackground (Color.lightGray);
       mText = new TextField("");   // field to enter mass value
       mText.reshape(20,20,50,20);  // locate at 20,20; 50 pixels wide and 20 pixels high
       add(mText);   // add field to window
       mLabel = new Label("mass");
       mLabel.reshape(20,40,50,20);  //locate label below textfield
       add(mLabel);  //add label to window
       fText = new TextField("");   // field to output force value
       fText.reshape(80,20,50,20);  // locate at 80,20; 50 pixels wide and 20 pixels high
       add(fText);   // add field to window
       fLabel = new Label("force");
       fLabel.reshape(80,40,50,20);  //locate label below textfield
       add(fLabel);  //add label to window
     }
     
    public void product() {
       double a = 5.0,force;
       force = m*a;      // m is found from handle event routine below
       fText.setText(String.valueOf(force));
     }
       
    public boolean handleEvent(Event e) {
       Rectangle mRect = mText.bounds();  // boundary of mass textfield
       if ((e.x == mRect.x) && (e.y == mRect.y))  // text entered in mass textfield
        {
          Double M = new Double(mText.getText ());  // convert string to Double object
          m = M.doubleValue();   // get value of mass from Double object
          product(); 
          return (true);
         }
        return super.handleEvent(e);  // take care of all other events
     }
}

The following applet shows you how to deal with a number of other types of events. After each event occurs, the program clears the window and prints a message listing the type of event.

import java.applet.Applet;
import java.awt.*;
import java.util.*;

public class HandleApplet extends Applet{
   int xMouse, yMouse;               // Current position of the mouse.   
   int xWindow, yWindow;             // Window width and height.         
   String sMessage = " "; 

    public void init (){
      xMouse = 0;
      yMouse = 0;
      xWindow = size().width;
      yWindow = size().height;
      setBackground (Color.lightGray);
     }

    public boolean handleEvent(Event evt){
      if (evt.id == Event.MOUSE_DOWN)
          {
            sMessage = "Mouse Down";
            xMouse = evt.x; 
            yMouse = evt.y;
            repaint ();
            return(true);
           }
       else if (evt.id == Event.MOUSE_UP)
          {
            sMessage = "Mouse Up"; 
            xMouse = evt.x; 
            yMouse = evt.y;
            repaint ();
            return(true);
           }
       else if (evt.id == Event.MOUSE_MOVE)
          {
            sMessage = "Mouse Move"; 
            xMouse = evt.x; 
            yMouse = evt.y;
            repaint ();
            return(true);
           }
       else if (evt.id == Event.MOUSE_DRAG)
          {
            sMessage = "Mouse Drag"; 
            xMouse = evt.x; 
            yMouse = evt.y;
            repaint ();
            return(true);
           }
        else if (evt.id == Event.KEY_PRESS)
          {
            sMessage = "Key Pressed"; 
            repaint ();
            return(true);
           }
        else if (evt.id == Event.KEY_ACTION)
          {
            sMessage = "Hot Key Pressed"; 
            repaint ();
            return(true);
           }
        return (super.handleEvent(evt));
      }

    public void paint (Graphics g){
        g.clearRect (0, 0, xWindow, yWindow);
        g.drawString (sMessage, xMouse, yMouse);
      }
  }

The program above is useful for carrying out a calculation, waiting for an event, and then carrying out another calculation. However, frequently we want to be able to interrupt a calculation while it is running. For example, we might have a simulation running and we want to interrupt the simulation to change a parameter. The following applet shows how to do this within the context of an animation. It is a simulation of a ball bouncing around in a box(defined by the window) with no air friction. When the user clicks the mouse, the ball moves to the position of the mouseclick. The simulation also allows the user to resize the window, so that the ball reflects off the new edges of the new window.

 import java.awt.*; import java.applet.*;

public class fall extends Applet implements Runnable 
{
    Thread runner;
    int x,y;   // ball location
    Image buffer;
    int curw,curh;  // window width and height
    int accel = 4,vx,vy;
    int bsize = 20;  //ball size in pixels
    int bsize1 = bsize + 1;
    
	public void init() {
		   x = y = bsize;  //initial conditions
		   vx = 6;
		   vy = 0;
	   }
	
	public void start() {
	    runner = new Thread(this);
	    runner.start();
	}
	
	public void stop() {
	    runner.stop();
	}

	public void run() {
	   while (true) {
	     if ((buffer == null) || ( curw!= size().width) || (curh!= size().height))
	      {
	        buffer = createImage(size().width, size().height);  // create graphics buffer
	        curw = size().width;
	        curh = size().height;
	      }
	   Rectangle oldRect = new Rectangle(x,y,bsize1,bsize1);
	   x += vx;
	   y += vy + 0.5*accel;   // midpoint algorithm which is exact for constant acceleration 
	   vy += accel;
	   Rectangle newRect = new Rectangle(x,y,bsize1,bsize1);
	   Rectangle r = newRect.union(oldRect);
	   Graphics g = buffer.getGraphics();
	   g.clipRect(r.x,r.y,r.width,r.height);
	   update(g);
	   g = getGraphics();
	   g.clipRect(r.x,r.y,r.width,r.height);
	   g.drawImage(buffer,0,0,this);
	   if (x  <= 0 && vx < 0)
	     vx = -vx;
	   else if (x + bsize >= size().width && vx > 0)
	     vx = -vx;
	   if (y  <= 0 && vy < 0)
	     vy = -vy;
	   else if (y + bsize >= size().height && vy > 0)
	     vy = -vy;
    try {Thread.sleep(25);}            // delay 25 msec between updates
    catch (InterruptedException e){};
	  }  
	}
	    
	public boolean handleEvent(Event evt){
      if (evt.id == Event.MOUSE_DOWN)
        {
          Graphics g = getGraphics();
          g.clearRect (0, 0, size().width, size().height);  // clear window
          x = evt.x; 
          y = evt.y;
          repaint();   // redraw window
          return(true);
        }
	   return (super.handleEvent(evt));
      }

	public void paint( Graphics g ) {
	   g.setColor(Color.red);
		  g.fillOval(x,y,bsize,bsize);
		  g.setColor(Color.blue);
		  g.drawString("Free Fall in a box",30,10);  // title
	  }
}

The above program includes a number of new features:

At the present time Java is significantly slower than other languages used for scientific programming. Hopefully, this will change in the future. For our purposes the main advantage of Java is its interactive nature and the ease of doing graphics that are platform independent. It is useful to be able to create data using another language and then be able to read the data in using Java. The following two programs show how to do file input and output. An excellent reference for this and other aspects of Java is the book "On to Java" by Patrick Henry Winston and Sundar Narasimhan(Addison-Wesley, 1996).

/*
Application that inputs numbers from a text file - 
reference page 135-143 in Onto Java */

import java.io.*;

public class TokensIn {

	public static void main(String args[]) throws IOException{
	  double x;
	  String s;
	    FileInputStream fis = new FileInputStream("abc.in");  // associate input stream to file
	    StreamTokenizer tokens = new StreamTokenizer(fis);  // divide input stream into tokens
	    int next = 0;
     // set next equal to next token and check for end of file.
	    while ((next = tokens.nextToken()) != tokens.TT_EOF) { 
	     if(next == tokens.TT_WORD){
	       s = tokens.sval;      // set s equal to string value of token
	       System.out.println(s); }
	     else {
	       x = tokens.nval;      // set x equal to numeric value of token
	       System.out.println(x); } }
	    fis.close();
  } 
} 


/*
Application that outputs numbers to a text file - reference page 181-183 in On to Java
*/
import java.io.*;

public class TokensOut {

	public static void main(String args[]) throws IOException{
	 double x;
	  FileOutputStream fos = new FileOutputStream("abc.out");  // associate output stream to file
	  PrintStream output = new PrintStream(fos);  // divide input stream into tokens
	  for(int k = 0;k < 10; k++) { 
	    x = k*5.1;      // set x equal to value of token
	    output.print(x);
	    output.print('\t');  // add tab between data, useful for using cricket graph
	    output.println(2*x); } // carriage return after printing x
	  fos.close();
  } 
} 

Note the following features of the above programs.

Our final example shows an Ising model simulation based on Program Ising in Chapter 17 of Gould & Tobochnik.

import java.applet.*;
import java.awt.*;
import java.util.*;

    public class isingApplet extends Applet implements Runnable
/***************************************************************************

     2-d Ising Model simulation - Java version of Program Ising, page 575
     of An Intorduction to Computer Simulation Methods by Harvey Gould and 
     Jan Tobochnik, Addison-Wesley, 1996. 

 ***************************************************************************/

    {
    int L = 20;                        // dimension of lattice
    int N = L*L;                       // number of spins
    int spin[][] = new int[L][L];      // array of walker coordinates
    double w[] = new double[10];       // Boltzmann weigts
    int t = 0;                         // time in MCS per spin
    double T = 2.269;                  // initial temperature = Tc
    Button bhot,bcold,bstop,bcont;
    Thread runner;
    boolean running = false;          // true if simulation is running
    Scrollbar sTemp;
    TextField tTemp,tTime;
    TextField tMag,tChi,tEner,tSH,tAccept;
    Label lTemp;
    int x,y;                          // current spin coordinates
    int shift=100;                    // x and y location of lattice corner
    int wcell = 5;                    // cell width
    double M = 0,M2 = 0,E = 0,E2 = 0;
    double Accept;
/***************************************************************************/


    public void init (){
     // set up window with buttons, textfields and  scrollbar
      setLayout(null);
      setBackground (Color.lightGray);
      tTime = new TextField ("t = " + String.valueOf(t));
      tTime.reshape(10,10,50,20);
      add(tTime);
      bhot = new Button("start hot");      // add buttons
      bhot.reshape(40,50,80,20);
      add(bhot);
      bcold = new Button("start cold");      
      bcold.reshape(140,50,80,20);
      add(bcold);
      bstop = new Button("stop");
      bstop.reshape(240,50,80,20);
      add(bstop);
      bcont = new Button("continue");
      bcont.reshape(340,50,80,20);
      add(bcont);
      lTemp = new Label("Temperature");   // Temperature Label
      lTemp.reshape(200,10,100,20);
      add(lTemp);
      // Temperature Scrollbar
      sTemp = new Scrollbar (Scrollbar.HORIZONTAL,(int) (100.0*T),5,0,500);
      sTemp.reshape(280,10,100,20);
      add(sTemp);
      tTemp = new TextField (String.valueOf(T));  // Temperture Textfield
      tTemp.reshape(400,10,50,20);
      add(tTemp);
      boltzmann();
      
      // Textfields for output of averages
      tMag = new TextField ("M/N = ");
      tMag.reshape(10,230,150,20);
      add(tMag);
      tChi = new TextField ("Susc = ");
      tChi.reshape(10,260,150,20);
      add(tChi);
      tEner = new TextField ("E/N = ");
      tEner.reshape(190,230,150,20);
      add(tEner);
      tSH = new TextField ("C = ");
      tSH.reshape(190,260,150,20);
      add(tSH);
      tAccept = new TextField ("Acceptance Ratio = ");
      tAccept.reshape(370,230,100,30);
      add(tAccept);
    }
      
    public void  start(){     // start thread
         runner = new Thread(this);
         runner.start();
       }

    public void stop(){     // stop thread
         runner.stop();
       }
       
    public void run(){       // run thread
        while(true) 
         {
          if (running)      // check to see if stop button pushed
            {
             MonteCarlo();
             averages();
            } //end if
            try {Thread.sleep(250);}           // check for events
            catch (InterruptedException e){};
          } //end while
        }
    public void MonteCarlo(){
        int dE;
        for (int i = 1;i <= N;i++)   // Begin Monte Carlo code
              {
               x = (int) (L*Math.random());  // random number between 0 and L-1
               y = (int) (L*Math.random());        
               dE = spin[x][y]*(spin[pbc(x-1)][y] + spin[pbc(x+1)][y] 
                           + spin[x][pbc(y-1)] + spin[x][pbc(y+1)]);
               if(w[dE+4] > Math.random())
                {
                  spin[x][y] = -spin[x][y];  // accept flip
	                 drawSpin();
	                 Accept++;    
                }
              }
         t++;   // increment time
      }                             
  
    public void drawSpin()   // draw spins 
     {
	     Graphics g = getGraphics();
         if(spin[x][y] == 1)
           g.setColor(Color.red);
         else
           g.setColor(Color.blue);
         g.fillRect(shift+x*wcell,shift+y*wcell,wcell,wcell);
         g.dispose();
      }
     
    public void averages()
       {
       double m=0,e=0,SH,Chi;
       for(int i=0;i < L; i++)
         for(int j=0;j < L; j++)
            {
              m += spin[i][j];
              e -= spin[i][j]*(spin[i][pbc(j+1)] + spin[pbc(i+1)][j]);
            }
       M +=  m;
       M2 += m*m;
       E += e;
       E2 += e*e;
       Chi = (1.0/(T*N))*((M2/t) - (M/t)*(M/t));
       SH = (1.0/(T*T*N))*((E2/t) - (E/t)*(E/t));
       // Print averages
       tTime.setText("t = " + String.valueOf(t));
       tMag.setText("Mag/N = " + String.valueOf(M/(t*N)).substring(0,5));
       tChi.setText("Susc. = " + String.valueOf(Chi));
       tEner.setText("E/N = " + String.valueOf(E/(t*N)));
       tSH.setText("C = " + String.valueOf(SH));
       tAccept.setText("Acceptance Ratio = " + String.valueOf(Accept/(t*N)));
       }
       
    public int pbc(int s) {   // periodic boundary conditions
          if(s == -1)
           return(L-1);
         else if(s == L)
           return(0);
         else
           return(s);
       }
    public void boltzmann(){
          for(int i=-4;i <= 4; i++)
             w[i+4] = Math.exp(-2.0*i/T);
        }

   public boolean handleEvent(Event evt){
                 if (evt.id == Event.ACTION_EVENT)
                    return action(evt,evt.arg);
                 return (super.handleEvent(evt)); }
                 
   public boolean action(Event evt, Object arg)
      {
      if ( evt.target == bcont)  // continue
        {
           running = true;
           return(true);
         }//end if
      else if ( evt.target == bhot)  // start hot
        {
          for (x = 0;x < L;x++)
            for (y = 0;y < L;y++)
              {
              if(Math.random() > 0.5)
                spin[x][y] = 1;
              else
                spin[x][y] = -1;
              drawSpin();
              }
            running = true;
            return(true);
         }//end if
      else if ( evt.target == bcold)  // start cold
        {
          for (x = 0;x < L;x++)
            for (y = 0;y < L;y++)
              {
               spin[x][y] = -1;
               drawSpin();
              }
            running = true;
            return(true);
         }//end if
      else if ( evt.target == bstop) // stop
        {
            running = false;
            return(true);
         }//end if
      else if ((evt.id == Event.SCROLL_ABSOLUTE) || (evt.id == Event.SCROLL_LINE_UP)
           || (evt.id == Event.SCROLL_LINE_DOWN) || (evt.id == Event.SCROLL_PAGE_UP)
           || (evt.id == Event.SCROLL_PAGE_DOWN) )
          {
            T = (double) ((((Integer) evt.arg).intValue())/100.0);
            tTemp.setText(String.valueOf(T));
            t = 0;
            M = M2 = E = E2 = Accept = 0;
            boltzmann(); 
            return(true);
           } 
      else if ( evt.target == tTemp)  // stop
        {
            Double Td = new Double(tTemp.getText());
            T =  Td.doubleValue();
            sTemp.setValue( (int) (T*100));
            t = 0;
            M = M2 = E = E2 = Accept = 0;
            boltzmann(); 
            return(true);
        }//end if
      return false;  
      }
}

The above program includes most of what one needs to run simulations in physics with user interaction. The main new features of the program are listed below.

The above programs show the power and ease of use of Java graphics and user interactions. Below we show three useful classes which can be used as templates for building programs which really utilize the object oriented power of Java. We list a template for a Frame. Attached to the Frame are a Panel where Buttons and TextFields for user interaction with the program are placed. Also, attached is a Canvas where the drawing can be done and calls to physics methods are made. Ideally, the user should define other classes which represent physical objects such as an Ising lattice, a particle moving in a potential, or a fractal. Also, it is common practive to place each class declaration in a separate file.

These templates can be used with applets. To do so eliminate the FrameTemplate class, and replace the GeneralFrame class by a class that extends the Applet class.

/* This template sets up a window frame and adds a panel of TextFields and Buttons and a 
canvas for drawing. The necessary changes for the user to make are to put in appropriate labels 
for the TextFields and Buttons in the init() method. There can be any number of TextFields
and Buttons. The number of labels should match the number of TextFields.  Most of the programming
effort is in creating the canvas */

import java.awt.*;

class FrameTemplate {
 
 public static void main(String args[])  {
       GeneralFrame frm = new GeneralFrame();   // set up window for application
       frm.setTitle("Project Title");
       frm.resize(500,300);
       frm.init();
       frm.show();
       frm.start();  }  } // end FrameTemplate
      

 class GeneralFrame extends Frame implements Runnable {
    sipPanel thisPanel;
    CanvasTemplate thisCanvas;
    Thread runner;

    public void init() {
	  String lstring[] = {"label 1", "label 2"};  // change and add labels for TextFields
	  String tstring[] = {String.valueOf(1),String.valueOf(1)};  // change and add values
	  String bstring[] = {"label 1 ", "label 2", "label 3"}; // change and add labels for Buttons 
	  setLayout(new BorderLayout());
	  thisPanel = new sipPanel(lstring,tstring,bstring);   // panel for Buttons and TextFields
	  add("North",thisPanel);
	  thisCanvas = new CanvasTemplate();   // Canvas for drawing and physics
	  add("Center", thisCanvas); }
	  
    public void start() {
	    runner = new Thread(this);
	    runner.start();  }
	
    public void stop() {
	    runner.stop();  }

    public void run() {
	   while(true) {
         try {Thread.sleep(1000);}  // delay 1000 msec between updates
         catch (InterruptedException e){};  } }

    public boolean handleEvent(Event evt){
       if (evt.id == Event.ACTION_EVENT)
                return action(evt,evt.arg);
       return (super.handleEvent(evt)); }
                 
    public boolean action(Event evt, Object arg){
	  for(int i = 0; i < thisPanel.buttons.length;i++) 
        if  (evt.target == thisPanel.buttons[i]) {     // button pushed
          thisCanvas.buttonAction(i);
          return(true); }
      for(int i = 0; i < thisPanel.texts.length;i++) 
        if  (evt.target == thisPanel.texts[i]) {     //  TextField changed
          Double R = new Double(thisPanel.texts[i].getText());
          thisCanvas.textAction(i,R.doubleValue());
          return(true); }
      return false; } }
      

/* The following class requires no modification from the user */

import java.awt.*;
    
 class sipPanel extends Panel  {
    TextField texts[];
    Label labels[];
    Button buttons[];
    
	public  sipPanel(String lstring[], String tstring[], String bstring[] ) {
	  setLayout(new FlowLayout());
	  int nT = lstring.length;
	  int nB = bstring.length;
	  texts = new TextField[nT];
	  labels = new Label[nT];
	  buttons = new Button[nB];

	 for(int i = 0; i < nT;i++) {
	    labels[i]= new Label(lstring[i]);
	    add(labels[i]);
	    texts[i]= new TextField(tstring[i]);
	    add(texts[i]); }
	 for(int i = 0; i < nB;i++) {
	    buttons[i] = new Button(bstring[i]);
	    add(buttons[i]); } } }

      
      
/* Below are the methods that must be defined so that CanvasTemplate will work with
  FrameTemplate and sipPanel. Each method in buttonAction must be written and 
  each variable in textAction must be declared. Other methods for drawing and 
  doing physics must be written as well. */ 
  
  
import java.awt.*;

class CanvasTemplate extends Canvas{
 /* Place object and variable declarations used by more than one method 
    or by other classes here  */  
 
    public CanvasTemplate() {
	 // Constructor. Place here code to be executed whenever new object created
	    }
          
    public void buttonAction(int i) {   
      switch(i) {
        case 0: method0(); break;   // method to be executed when button 0 pushed
        case 1: method1(); break;
        case 2: method2(); }  }
    
    public void textAction(int i, double value) {
      switch(i) {
        case 0: N0 = (int) value; break;  // convert to an integer
        case 1: N1 =  value; }  } }  // leave as a double