/*  hrdarth.c   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include "tmpglob.h"
#include "artherr.h"
#include "yacintfc.h"
#ifdef INTERACTIVE
#include "cgidbg.h"
#include "dspe_app.h"
#endif

const char * ArithTypeName = "int16" ;
const char * ArithFormat = "%6d" ;
const char * ArithBinaryFormat = "0x%04x" ;

const int16 MachWord::max_positive = 0x7fff ;
const int16 MachWord::min_negative = 0x8000 ;
const int16 MachWord::max_int_positive = 0x7fff ;
const int16 MachWord::min_int_negative = 0x8000 ;
const uint16 MachWord::max_unsigned_int = 0x8000 ;

const int32 AccMachWord::max_positive = 0x7fffffff ;
const int32 AccMachWord::min_negative = 0x80000000 ;

MachWord check_overflow(double test_val,int32& number_overflows)
{
	int warn=0;
	if (test_val > MachWord::max_positive)
		test_val = MachWord::max_positive,warn=1 ;
	if (test_val < MachWord::min_negative)
		test_val = MachWord::min_negative,warn=1 ;
	number_overflows += warn ;
	return (MachWordCast) test_val ;
}

AccMachWord check_overflow_acc(double test_val,int32& number_overflows)
{
    number_overflows += ArithAccCheckOverflow(test_val);
    return (AccMachWordCast)  test_val ;
}


CxMachWord::operator complex() const
{
    return complex((int16)rl, (int16)ig);
}




MachWord::MachWord(double v)
{
	value = NormToMachWord(v);
}


MachWord::MachWord(unsigned int v)
{
	if (v > 0xffff) {
		v = 0xffff ;
    	State.Warning("unsigned MachWord overflow, hard limited");
#ifdef INTERACTIVE
		if (DspApplication::is_trace()) TheLog <<
			"unsigned MachWord overflow, hard limited.\n"  ;
#endif
	}
	*(uint16 *) &value = v ;
}

MachWord::MachWord(int v)
{
	int warn = 0 ;
	if (v < 0) {
        if (v < min_negative) v = min_negative,warn=1 ;
    } else {
        if (v > max_positive) v = max_positive,warn=1 ;
    }
    if (warn) hard_limit_warn();
    value = v ;
}

AccMachWord::AccMachWord(uint32 v)
{
	*(uint32 *) &value = v ;
}

AccMachWord::AccMachWord(double v)
{
	value = NormToAccMachWord(v);
}

double NormFromMachWord(double val)
{
	val /= NormToOneMachWord ;
	return val ;
}

double NormFromAccMachWord(double val)
{
	val /= NormToOneMachWord ;
	return val ;
}

