import java.io.*;
import java.lang.Double;
import java.lang.Long;
import java.lang.Math;
import java.lang.String;

public class rwinfnanbinary
{
    public static final String Progname = "rwinfnanbinary";

    public static void main(String[] args) throws IOException
    {
	double x, y, z;

	test_inf(1.0, 0.0);		// generate a positive Infinity
	test_inf(-1.0, 0.0);		// generate a negative Infinity
	test_nan(0.0, 0.0);		// generate a positive NaN
	// test_nan(Math.sqrt(-0.0), 0.0);	// generate a negative NaN
	test_nan(-0.0, 0.0);		// generate a negative NaN
    }

    public static String doubleToHexadecimal(double x)
    {
	long lx = Double.doubleToLongBits(x);
	String s = Long.toHexString(lx);

	return ("0x" + s);
    };

    public static void read_and_check(String inname) throws IOException
    {
	DataInputStream in = new DataInputStream(new FileInputStream(inname));
	// ObjectInputStream  in = new ObjectInputStream(new FileInputStream(inname));

	double x, y, z, expect;

	// System.out.println("========================================================================");

	x = y = z = -999;
	x = in.readDouble();
	in.readChar();       // discard separator space
	y = in.readDouble();
	in.readChar();       // discard separator space
	expect = x / y;

	z = in.readDouble();
	System.out.println("Read from Unicode binary file:");
	System.out.print  ("\t" + x + " [" + doubleToHexadecimal(x) + "] / ");
	System.out.print  (y + " [" + doubleToHexadecimal(y) + "] -> ");
	System.out.println(z + " [" + doubleToHexadecimal(z) + "]");
	System.out.print  ("\tExpected: " + expect + " [" + doubleToHexadecimal(expect) + "]");
	if (Double.isNaN(z))
	    System.out.println(Double.isNaN(expect) ? " [correct]" : " [INCORRECT]");
	else if (Double.isInfinite(z))
	    System.out.println(Double.isInfinite(expect) ? " [correct]" : " [INCORRECT]");
	else
	    System.out.println((!Double.isInfinite(expect) &&
				!Double.isNaN(expect) &&
				(z == expect)) ? " [correct]" : " [INCORRECT]");

	in.close();
	System.out.println("========================================================================");
    }

    public static void test_inf(double x, double y) throws IOException
    {
	String tmpname = Progname + ".tmp.inf";
	// FileOutputStream tmpfile = new FileOutputStream(tmpname);
	DataOutputStream tmpfile = new DataOutputStream(new FileOutputStream(tmpname));
	PrintWriter output = new PrintWriter(tmpfile);
	double z = x / y;

	System.out.println("This line should read: " + x + "/" + y + " -> +/-Infinity");
	System.out.println(x + "/" + y + " -> " + z);

	// output.println(x + " " + y + " " + z);
	tmpfile.writeDouble(x);
	tmpfile.writeChar(' ');
	tmpfile.writeDouble(y);
	tmpfile.writeChar(' ');
	tmpfile.writeDouble(z);

	if (z != z)
	   System.out.println("INCORRECT comparison of Infinities with !=");
	if (z == z)
	   System.out.println("Correct comparison of Infinities with ==");

	if (!Double.isInfinite(z))
	   System.out.println("INCORRECT test of Infinities with isInfinite()");
	if (Double.isInfinite(z))
	   System.out.println("Correct test of Infinities with isInfinite()");

	tmpfile.close();
	read_and_check(tmpname);
    }

    public static void test_nan(double x, double y) throws IOException
    {
	String tmpname = Progname + ".tmp.nan";
	// FileOutputStream tmpfile = new FileOutputStream(tmpname);
	DataOutputStream tmpfile = new DataOutputStream(new FileOutputStream(tmpname));
	PrintWriter output = new PrintWriter(tmpfile);
	double z = x / y;

	System.out.println("This line should read: " + x + "/" + y + " -> +/-NaN");
	System.out.println(x + "/" + y + " -> " + z);

	// output.println(x + " " + y + " " + z);
	tmpfile.writeDouble(x);
	tmpfile.writeChar(' ');
	tmpfile.writeDouble(y);
	tmpfile.writeChar(' ');
	tmpfile.writeDouble(z);

	if (z == z)
	   System.out.println("INCORRECT comparison of NaNs with !=");
	if (z != z)
	   System.out.println("Correct comparison of NaNs with ==");

	if (!Double.isNaN(z))
	   System.out.println("INCORRECT test of NaNs with isNaN()");
	if (Double.isNaN(z))
	   System.out.println("Correct test of NaNs with isNaN()");
	tmpfile.close();
	read_and_check(tmpname);
    }
}
