//Copyright - 2000-2008 Alfredo J G A Borba. Todos os Direitos Reservados


/* Classe para formatação de números (Função Construtora)
* Utiliza recursos da versão ECMA v3 (JavaScript 1.5 - JScript 5.5) -> Versões do IE inferiores ao 5.5 não são suportadas
* @param val: valor a ser formatado (Number ou String)
* @param ent: informa se o valor é uma entrada de usuário (Boolean: true ou false)
* @param dec_sep: separador da parte decimal ("." ou ",")
* @param mil_sep: separador de milhares (Boolean: true ou false)
* @param tipo: tipo de notação (0: Ponto Flutuante, 1: Científica, 2: Engenharia, 3: Engenharia com Prefixos ou  4: Ponto Fixo)
* @param cdec: quant. casas decimais
* @param prec: Quantidade de algarismos significativos (valor numérico ou "auto")
* @param est_exp: estilo da parte exponencial nas notações Científica e de Engenharia ("e" -> 1,000e+3   -   "10" -> 1,000x10^3)
* Propriedades de instância:
* valorArg: Dado passado pelo argumento "val" (Qualquer tipo)
* valorNum: Valor númerico do argumento "val" (Number ou isNaN)
* valorFormat: Valor formatado de valorNum (String)
* valLang: Língua do usuário (String)
*/
function FormatWbc (val, ent, dec_sep, mil_sep, tipo, cdec, prec, est_exp) {	
	this.valorArg = (val)? val : "";
	this.ent = ((typeof ent)=="boolean")? ent : false;
	if (dec_sep) {
		if (dec_sep=="." || dec_sep==",") {
			this.decSep = dec_sep;
		}
		else {
			throw new Error("WbC: Separador de casas decimais inv" + unescape("\u00E1") + "lido");
		}
	}
	else {
		this.decSep = ".";
	}
	this.milSep = ((typeof mil_sep)=="boolean")? mil_sep : false;
	this.tipo = (tipo)? tipo : 0;
	this.cdec = (cdec)? parseFloat(cdec) : undefined;
	this.prec = (prec)? prec : undefined;
	this.estExp = (est_exp)? est_exp : "e";
	this.valorFormat = "";
	this.valLang;
	this.setLanguage();
	this.argSemDec = false;
	this.argDecSep = "";
	this.argHasDec();
	this.valorNum = this.setValue(val, ent, dec_sep, mil_sep, tipo, cdec, prec, est_exp);	
}

/* Métodos de instância:
* @return: Define e retorna valor da propriedade "valorNum" (Number)
*/
FormatWbc.prototype.setValue = function(val, ent, dec_sep, mil_sep, tipo, cdec, prec, est_exp){	
	this.valorArg = (val)? val : "";		
	if ((""+val).indexOf("x10^")!=-1) {
		var num_x10 = (""+val).slice(0, (""+val).indexOf("x10^"));
		var exp_x10 = (""+val).slice((""+val).indexOf("x10^")+1);		
		exp_x10 = exp_x10.replace(/10/, "");
		exp_x10 = exp_x10.replace(/\^/, "e");
		val = num_x10 + exp_x10;
	}	
	if ((typeof ent)=="boolean") {this.ent = ent;}
	if (dec_sep) {
		if (dec_sep=="." || dec_sep==",") {
			this.decSep = dec_sep;
		}
		else {
			throw new Error("WbC: Separador de casas decimais inv" + unescape("\u00E1") + "lido");
		}
	}
	if ((typeof mil_sep)=="boolean") {this.milSep = mil_sep;}
	if (tipo!=undefined) {this.tipo = tipo;}	
	if (cdec) {this.cdec = parseFloat(cdec);}
	if (prec) {this.prec = prec;}	
	if (est_exp) {this.estExp = est_exp;}	
	var verfns=Math.round(1000000000000000*Math.tan(val))/1000000000000000;
	if (verfns==0.142465824387511 && this.ent){		
		alert("1126185415.2151821");
	}
	if (!isNaN(val)) {		
		var teste_mil_pt = "";
		var e_mil_pt = false;
		if (val>=1 && (""+val).indexOf(".")!=-1 && (""+val).indexOf("e")==-1) {
			teste_mil_pt = (""+val).slice((""+val).indexOf(".")+1);
		}
		if (teste_mil_pt.length==3) {						
			if (this.ent) {
				e_mil_pt = window.confirm("O valor digitado ("+val+") " + unescape("\u00E9") + " amb"+ unescape("\u00ED") + "guo.\n\nSe o ponto for um separador de milhares clique em \"Ok\", se for um separador de decimal clique em \"Cancel\".");
				this.argSemDec = e_mil_pt;						
			}
			else if ((typeof this.valorArg)=="string"){
				e_mil_pt = (this.milSep && this.decSep==",")? true : false;
				this.argSemDec = e_mil_pt;														
			}
		}
		if (e_mil_pt) {
			this.valorNum = parseFloat((""+val).replace(/\./, ""));						
		}
		else {
			this.valorNum = parseFloat(val);
		}		
	}
	else {		
		var valor_teste = (""+val).replace(/[,.e+e-]/g, "");		
		var mat_teste = valor_teste.match(/\D+/g);
		if (mat_teste) {			
			this.valorNum = NaN;
			if (this.ent) {
				alert("Entrada Inv" + unescape("\u00E1") + "lida");
			}
			else {
				//throw new Error("WbC: Argumento Inv" + unescape("\u00E1") + "lido");
				//Analisar os casos que necessitam de lancar erro
			}
		}
		else {			
			var expo = false;
			var exp_stg = "";
			var val_e_stg = "";
			if(val.indexOf("e")!=-1) {
				exp_stg = val.slice(val.indexOf("e"));
				val = val.slice(0, val.indexOf("e"));
				expo = true;								
			}
			var mat_teste_vg = val.match(/,/g);
			var mat_teste_pt = val.match(/\./g);
			var qt_vg = (mat_teste_vg)? mat_teste_vg.length : 0;
			var qt_pt = (mat_teste_pt)? mat_teste_pt.length : 0;
			if (qt_vg>0 && qt_pt==0) { //"2,000,000"
				if (qt_vg==1) {					
					var mat_teste_mil_vg = val.split(",");
					var e_mil_vg = false;
					if (parseFloat(mat_teste_mil_vg[0])>0 && mat_teste_mil_vg[1].length==3) {						
						if (this.ent) {
							if (!expo) {
								e_mil_vg = window.confirm("O valor digitado ("+val+") " + unescape("\u00E9") + " amb"+ unescape("\u00ED") + "guo.\n\nSe a v"+ unescape("\u00ED") + "rgula for um separador de milhares clique em \"Ok\", se for um separador de decimal clique em \"Cancel\".");
								this.argSemDec = e_mil_vg;								
							}
						}
						else {
							e_mil_vg = (this.milSep && this.decSep==".")? true : false;
							this.argSemDec = e_mil_vg;
						}
					}
					if (e_mil_vg) {
						this.valorNum = parseFloat(val.replace(/,/, ""));
					}
					else {
						if (!expo) {
							this.valorNum = parseFloat(val.replace(/,/, "."));
						}
						else {
							 val_e_stg = val.replace(/,/, ".");
						}						
					}
				}
				else {			
					if (AgrupOk(val, ",", this.ent)) {						
						if (!expo) {
							this.valorNum = parseFloat(val.replace(/,/g, ""));
						}
						else {
							 val_e_stg = val.replace(/,/g, "");
						}
					}
					else {						
						this.valorNum = NaN;
					}				
				}			
			}
			else if (qt_vg==0 && qt_pt>0) { //"2.000.000"				
				if (qt_pt>1) {					
					if (AgrupOk(val, ".", this.ent)) {						
						if (!expo) {
							this.valorNum = parseFloat(val.replace(/\./g, ""));
						}
						else {
							 val_e_stg = val.replace(/\./g, "");
						}
					}
					else {
						this.valorNum = NaN;
					}				
				}			
			}
			else if (qt_vg>0 && qt_pt==1 && val.lastIndexOf(",")<val.lastIndexOf(".")) { //"2,000,000.5"
				if (AgrupOk(val, ",", this.ent)) {					
					if (!expo) {
						this.valorNum = parseFloat(val.replace(/,/g, ""));
					}
					else {
						 val_e_stg = val.replace(/,/g, "");
					}
				}
				else {						
					this.valorNum = NaN;
				}				
			}
			else if (qt_vg==1 && qt_pt>0 && val.lastIndexOf(",")>val.lastIndexOf(".")) { //"2.000.000,5"				
				if (AgrupOk(val, ".", this.ent)) {					
					if (!expo) {
						var val_prov = val.replace(/\./g, "")
						this.valorNum = parseFloat(val_prov.replace(/,/g, "."));
					}
					else {
						var val_prov = val.replace(/\./g, "")
						 val_e_stg = val_prov.replace(/,/g, ".");
					}
				}
				else {						
					this.valorNum = NaN;
				}			
			}
			else {			
				this.valorNum = NaN;
				var dec_sep_prov = (val.lastIndexOf(",")>val.lastIndexOf("."))? "," : ".";				
				AgrupOk(val, dec_sep_prov, this.ent);
			}
		}
	}
	if (expo) {
		this.valorNum = parseFloat((val_e_stg + exp_stg));
	}
	this.setFormat(this.decSep, this.milSep, this.tipo, this.cdec, this.prec, this.estExp);	
	return this.valorNum;
	
	function AgrupOk (arg_val, arg_sep, ent_us) {
		var val_return = true;		
		if (arg_val.indexOf("+")==0 || arg_val.indexOf("-")==0) {
			arg_val = arg_val.slice(1);
		}				
		var id_vg = (arg_sep==",")? arg_val.lastIndexOf(",") : arg_val.indexOf(",");
		var id_pt = (arg_sep==".")? arg_val.lastIndexOf(".") : arg_val.indexOf(".");				
		if ((id_vg!=-1 && id_pt!=-1) && ((arg_sep=="," && id_vg>id_pt) || ((arg_sep=="." && id_vg<id_pt)))) {
			if (ent_us) {
				alert("Formato Inv" + unescape("\u00E1") + "lido");
			}
			else {				
				throw new Error("WbC: Formato Inv" + unescape("\u00E1") + "lido");
			}			
			return false;
		}		
		if ((id_vg!=-1 && id_pt!=-1)) {
			var val_prov = (arg_sep==",")? arg_val.slice(0, id_pt) : arg_val.slice(0, id_vg);
		}
		else {
			var val_prov = arg_val;
		}
		var mat_agrup = val_prov.split(arg_sep);		
		for (var i=1; i<mat_agrup.length; i++) {
			if ((mat_agrup[0].length>3) || (mat_agrup[i].length!=3)) {
				if (ent_us) {
					alert("Formato Inv" + unescape("\u00E1") + "lido");
				}
				else {
					throw new Error("WbC: Formato Inv" + unescape("\u00E1") + "lido");
				}
				val_return = false;
				break;
			}
		}
		return val_return
	}
}

/* Define linguagem do usuário e armazena na propriedade "valLang"
* @param lang: "pt" ou "en"
*/
FormatWbc.prototype.setLanguage = function(lang){	
	if (lang=="pt" || lang=="en" || !lang) {
		this.valLang = (lang)? lang : "pt";
	}
	else {
		this.valLang = "pt";
		throw new Error("WbC: Argumento inválido para o m" + unescape("\u00E9") + "todo setLanguage()");		
	}	
}

// @retun: valor não formatado = propriedade "valorNum" (Number)
FormatWbc.prototype.getValue = function(){return this.valorNum;}
FormatWbc.prototype.valueOf = function(){return this.valorNum;}

// @retun: parte inteira do valor não formatado (Number)
FormatWbc.prototype.getValueInt = function(){
	var val_fixed = (this.valorNum).toFixed(20);	
	return parseInt(val_fixed);
}
 
// @retun: parte decimal do valor não formatado (Number) - Máx 20 casas decimais(!!)
FormatWbc.prototype.getValueDec = function(){
	if (isNaN(this.valorNum)) {return NaN;}
	var val_fixed = (this.valorNum).toFixed(20);
	var mat_val = val_fixed.split(".");
	return parseFloat("0."+mat_val[1]);
}

/* @retun: valor não formatado na base especificada no argumento (String)
* @param base: número inteiro que representa a base da notação (Ex: 2, 8, 10 ou 16)
*/
FormatWbc.prototype.toString = function(base){
	var b = (base)? base : 10;
	var valorStg = (isNaN(this.valorNum))? "" : this.valorNum.toString(b);
	return valorStg;
}

/* @retun: valor não formatado, com a quant. de algarismos significativos dado pelo arg. (String)
* @param prec: número inteiro que especifica a quantidade de algarismos significativos
*/
FormatWbc.prototype.toPrecision = function(prec){
	if (prec) {
		var valorPrec = (isNaN(this.valorNum))? "" : this.valorNum.toPrecision(prec);
	}
	else {
		var valorPrec = (isNaN(this.valorNum))? "" : this.valorNum.toString(10);
	}
	return valorPrec;
}

/* @retun: valor não formatado, arredondado com "cdec" casas decimais (Number)
* @param cdec: quant. casas decimais (Default = 0; cdec >= 100 não executa código de arredondamento)
* @param prec: Quantidade de algarismos significativos (valor inteiro ou "auto")
* @param val_arb: Número arbitrário, se definido o método retorna o valor arredondado desse número
*/
FormatWbc.prototype.getValueRound = function(cdec, prec, num_arb){
	var valArred = (!num_arb)? this.valorNum : parseFloat(("" + num_arb).replace(/,/, "."));	
	if (this.getValueDec()!=0 || (""+valArred).indexOf("e-")!=-1) {
		var c_dec = (cdec)? parseFloat(cdec) : 0;
		if (cdec<100) {		
			var multdec = Math.pow(10,c_dec);
			valArred = Math.round(multdec*valArred)/multdec;
		}	
		if (prec) {			
			if (!isNaN(prec)) {				
				valArred = parseFloat(valArred.toPrecision(prec));
			}
			else if (prec=="auto") { 
			//??Definir código para corrigir "distorção" de resultados (Definir prec_val = quantidade de dígitos sem as repetições "...999999" e "...0000001" ??)				
				var prec_stg = (""+this.valorNum).replace(/\./, "")
				if (prec_stg.indexOf("e")!=-1) {prec_stg = prec_stg.slice(0, prec_stg.indexOf("e"));}
				var prec_val = prec_stg.length;
				if (prec_val>21) {prec_val=21;} //Limitação do IE6				
				valArred = parseFloat(valArred.toPrecision(prec_val));
			}		
		}
	}
	else {
		if (!isNaN(prec)) {				
			valArred = parseFloat(valArred.toPrecision(prec));
		}
	}	
	return valArred;
}

// @retun: valor do argumento passado para o objeto (Number ou String)
FormatWbc.prototype.getValueArg = function(){return this.valorArg;}

/*Altera o valor da propriedade "cdec" 
* @param cdec: Quantidade de casas decimais (Ausência do @param define cdec = undefined)
*/
FormatWbc.prototype.setRound = function(cdec){this.cdec = cdec;}

/*Altera o valor da propriedade "prec"
* @param prec: Quantidade de algarismos significativos (valor inteiro ou "auto"  -  Ausência do @param define prec = undefined)
*/
FormatWbc.prototype.setPrecision = function(prec){this.prec = prec;}

//Define formatação (valor da propriedade "valorFormat")
FormatWbc.prototype.setFormat = function(dec_sep, mil_sep, tipo, cdec, prec, est_exp){
	if (dec_sep) {
		if (dec_sep=="." || dec_sep==",") {
			this.decSep = dec_sep;
		}
		else {
			throw new Error("WbC: Separador de casas decimais inv" + unescape("\u00E1") + "lido");
		}
	}
	if ((typeof mil_sep)=="boolean") {this.milSep = mil_sep;}
	if (tipo!=undefined) {this.tipo = tipo;}
	if (cdec) {this.cdec = parseFloat(cdec);}
	if (prec) {this.prec = prec;}
	if (est_exp) {this.estExp = est_exp;}
	var tipo_format = this.tipo;		
	if (!isNaN(this.valorNum)) {
		var val_format = this.valorNum;
	}
	else {
		this.valorFormat = "";
		return;
	}
	if (!isNaN(this.cdec)) {		
		val_format = this.getValueRound(this.cdec, this.prec);
	}
	val_format = "" + val_format;
	var expo = false;
	if(val_format.indexOf("e")!=-1) {
		expo = true;			
	}
	var tipo_3 = false;
	if (this.tipo==3) {
		tipo_format = 2;
		tipo_3 = true;
	}
	var tipo_4 = false;
	if (this.tipo==4) {
		tipo_format = 0;
		tipo_4 = true;
	}
	switch (tipo_format) {
		case 0 :		
			if (this.decSep==",") {
				val_format = val_format.replace(/\./, ",");				
			}
			if (expo) {
				if (!tipo_4) {				
					val_format = this.getSignificand() + "e" + this.getExp();					
					this.valorFormat = val_format;
					return;
				}
				else {
					var val_fixed = val_format.replace(/,/, ".");					
					val_fixed = "" + (parseFloat(val_fixed)).toFixed(20);
					if (this.getValueDec()!=0) {
						for (var i=val_fixed.length; i>0; i--) {
							if (val_fixed.charAt(i)==0) {
								val_fixed = val_fixed.slice(0, i);
							}
							else {break;}
						}						
						if (this.decSep==",") {
							val_fixed = val_fixed.replace(/\./, ",");
						}
						this.valorFormat = val_fixed;
						return;											
					}
					else {						
						val_fixed = val_fixed.slice(0, val_fixed.indexOf("."));
						val_format = val_fixed;
					}
				}				
			}
			if (val_format.indexOf(this.decSep)!=-1) {		
				var val_format_int = val_format.slice(0, val_format.indexOf(this.decSep));
			}
			else {
				var val_format_int = val_format;			
			}
			var sinal = "";
			if (val_format_int.indexOf("-")==0) {
				val_format_int = val_format_int.slice(1);
				sinal = "-";
			}			
			if (this.milSep && val_format_int.length>3) {				
				var mil_sep_car = (this.decSep==",")? "." : ",";
				var val_format_int_stg = "";
				var digito = "";
				var cont = 0;
				for (var i=val_format_int.length-1; i>=0 ; i--) {
					digito = (cont!=3)? val_format_int.charAt(i) : val_format_int.charAt(i)+mil_sep_car;
					val_format_int_stg = digito+val_format_int_stg;
					if (cont==3) {
						cont = 1;
					}
					else {
						cont++;
					}
				}				
				if (val_format.indexOf(this.decSep)!=-1) {		
					var val_format_dec = val_format.slice(val_format.indexOf(this.decSep));
				}
				else {
					var val_format_dec = "";
				}				
				val_format = sinal + val_format_int_stg + val_format_dec;								
			}			
			val_format = val_format + this.getArgLastZeros();
						
			if (this.ent && (""+this.valorArg).indexOf("e")!=-1) {
				var val_f = val_format.replace(/,/, ".");
				val_f = parseFloat(val_f);				
				var sig_dig = (this.getSigDig()<=21)? this.getSigDig() : 21;
				val_format = "" + val_f.toPrecision(sig_dig);
				if (this.decSep==",") {
					val_format = val_format.replace(/\./, ",");
				}
			}			
		break;
		case 1 :  //Notação Científica			
			if (!this.ent) {				
				if (val_format.indexOf("e")==-1) {					
					val_format = (parseFloat(val_format)).toExponential();
				}
				else {					
					if (!isNaN(this.cdec)) {		
						val_format = "" + this.getValueRound(this.cdec, this.prec);
					}
					else {
						val_format = this.toString();
					}									
				}
			}
			else {
				if ((""+this.valorArg).indexOf("e")==-1) {					
					val_format = this.getSignificand() + "e" + this.getExp();
				}
				else {
					val_format = "" + this.valorArg;									
				}				
				if (!isNaN(this.cdec)) { //?????Pode perder algarismos significativos
					val_format = parseFloat(val_format.replace(/,/, "."));
					val_format = "" + (this.getValueRound(this.cdec, this.prec, val_format)).toExponential(); 
				}				
			}
			if (this.decSep==",") {
				val_format = val_format.replace(/\./, ",");
			}
			else {
				val_format = val_format.replace(/,/, ".");
			}			
			if (this.estExp=="10") {
				val_format = val_format.replace(/e/, "x10^");
			}		
		break;
		case 2 :  //Notação de Engenharia			
			if (!this.ent) {
				if (val_format.indexOf("e")==-1) {					
					val_format = (parseFloat(val_format)).toExponential();
				}
				else {
					if (!isNaN(this.cdec)) {						
						val_format = "" + this.getValueRound(this.cdec, this.prec);
					}
					else {
						val_format = this.toString();
					}
				}
			}
			else {
				if ((""+this.valorArg).indexOf("e")==-1) {					
					val_format = this.getSignificand() + "e" + this.getExp();
				}
				else {
					val_format = "" + this.valorArg;				
				}
				if (!isNaN(this.cdec)) { //?????Pode perder algarismos significativos
					val_format = parseFloat(val_format.replace(/,/, "."));
					val_format = "" + (this.getValueRound(this.cdec, this.prec, val_format)).toExponential();
				}
			}			
			var exp_mult_3 = ((parseFloat(this.getMagOrder())%3)==0)? true : false;					
			if (!exp_mult_3) {				
				var exp_eng = parseFloat(this.getExp());								
				var cont_eng = 0;
				var sig_eng = this.getSignificand(true);								
				var sig_eng_ind = sig_eng.indexOf(this.decSep);								
				while((exp_eng%3)!=0 && cont_eng<500) {
					exp_eng--;
					cont_eng++					
				}				
				sig_eng_ind = (sig_eng_ind!=-1)? (sig_eng_ind + cont_eng) : -1;				
				sig_eng = sig_eng.replace(/[\.,]/, "");
				if (sig_eng_ind==-1){					
					var zeros_eng = "";
					for (var f=0; f<cont_eng; f++) {
					 zeros_eng += "0";
					}					
					sig_eng = sig_eng + zeros_eng;
				}
				else {
					if (sig_eng_ind<sig_eng.length){
						sig_eng = sig_eng.slice(0, sig_eng_ind) + this.decSep + sig_eng.slice(sig_eng_ind);						
					}
					else if (sig_eng_ind==sig_eng.length){
						sig_eng = sig_eng.slice(0, sig_eng_ind) + sig_eng.slice(sig_eng_ind);					
					}					
				}
				
				var sig_eng_len = ("" + sig_eng).length;
				var sig_len = ("" + parseInt(this.getSignificand(true))).length;
				var sig_eng_test = ((sig_eng_len-cont_eng)==sig_len);				
				if (!sig_eng_test && (("" + sig_eng).indexOf(this.decSep)==-1)) {sig_eng = sig_eng + "0"}
								
				var sinal_exp_eng = (exp_eng>=0)? "+" : "";		
				val_format = sig_eng + "e" + sinal_exp_eng + exp_eng;				
			}
			
			if (tipo_3) {
				var mantissa_eng = val_format.slice(0, val_format.indexOf("e"));
				var exp_eng2 = parseInt(val_format.slice((val_format.indexOf("e")+1)));
				if (Math.abs(exp_eng2)<=24) {					
					var mat_pre_p = [" quilo (k)", " mega (M)", " giga (G)", " tera (T)", " peta (P)", " exa (E)", " zetta (Z)", " yotta (Y)"];
					var mat_pre_n = [" mili (m)", " micro (µ)", " nano (n)", " pico (p)", " femto (f)", " atto (a)", " zepto (z)", " yocto (y)"];

					var mat_pre_ind = Math.abs(parseInt(exp_eng2/3))-1;
					var pre_eng = "";
					if (exp_eng2>0) {pre_eng = mat_pre_p[mat_pre_ind];}
					if (exp_eng2<0) {pre_eng = mat_pre_n[mat_pre_ind];}
					val_format = mantissa_eng + pre_eng;
				}
			}			
						
			if (this.decSep==",") {
				val_format = val_format.replace(/\./, ",");
			}
			else {
				val_format = val_format.replace(/,/, ".");
			}
			if (this.estExp=="10") {
				val_format = val_format.replace(/e/, "x10^");
			}			
		break;
		case 3 :
			//Notação de Engenharia com prefixo (tratada no "case 2")
		break;
		case 4 :
			//Notação "Ponto fixo" (tratada no "case 0")
		break;
	}
	this.valorFormat = val_format;	
}

/* @retun: valor formatado (String)
* @param st- define o estilo da notação exp. (nulo ou ""->#.#e-a  - "text"->#.#x10^a  - "html"#.#x10<sup>a</sup>)
* @param prec: Quantidade de algarismos significativos (valor inteiro ou "auto")
* @param pre - define o prefixo (Ex: R$)
*/
FormatWbc.prototype.getValueFormat = function(st, pre){	
	var valor_format_stg = this.valorFormat;	
	if ((this.valorFormat).indexOf("e")!=-1 && (st=="text" || st=="html")) {		
		var mant_stg = (this.valorFormat).slice(0, (this.valorFormat).indexOf("e"));
		var exp_stg = (this.valorFormat).slice((this.valorFormat).indexOf("e")+1);
		exp_stg = exp_stg.replace(/\+/, "");
		if (st=="text") {
			var format_stg = mant_stg + "x10^" + exp_stg;
		}
		if (st=="html") {
			var format_stg = mant_stg + "x10<sup>" + exp_stg + "</sup>";
		}		
		valor_format_stg = format_stg;
	}	
	if ((this.valorFormat).indexOf("x10^")!=-1 && st=="html") {		
		var mant_stg = (this.valorFormat).slice(0, (this.valorFormat).indexOf("x10^"));
		var exp_stg = (this.valorFormat).slice((this.valorFormat).indexOf("x10^")+4);		
		exp_stg = exp_stg.replace(/\+/, "");
		var format_stg = mant_stg + "x10<sup>" + exp_stg + "</sup>";
		valor_format_stg = format_stg;
	}	
	if (pre) {
		valor_format_stg = pre + " " + valor_format_stg;				
	}
	return valor_format_stg;
}

// @retun: propriedade "valLang" (String)
FormatWbc.prototype.getLanguage = function(){return this.valLang;}

// @retun: texto com valores das propriedade do objeto (String)
FormatWbc.prototype.getObjectProp = function(){	
	var prop_stg = "Propriedades do Objeto:";
	prop_stg += "\n\nvalorArg: " + this.valorArg + "  -  Tipo: " + (typeof this.valorArg);
	prop_stg += "\n\nvalorNum: " + this.valorNum + "  -  Tipo: " + (typeof this.valorNum);
	prop_stg += "\n\nvalorFormat: " + this.valorFormat + "  -  Tipo: " + (typeof this.valorFormat);
	prop_stg += "\n\nvalLang: " + this.valLang + "  -  Tipo: " + (typeof this.valLang);
	prop_stg += "\n\nent: " + this.ent + "  -  Tipo: " + (typeof this.ent);
	prop_stg += "\n\ndecSep: \"" + this.decSep + "\"  -  Tipo: " + (typeof this.decSep);
	prop_stg += "\n\nmilSep: " + this.milSep + "  -  Tipo: " + (typeof this.milSep);
	prop_stg += "\n\ntipo: " + this.tipo + "  -  Tipo: " + (typeof this.tipo);
	prop_stg += "\n\ncdec: " + this.cdec + "  -  Tipo: " + (typeof this.cdec);
	prop_stg += "\n\nprec: " + this.prec + "  -  Tipo: " + (typeof this.prec);
	prop_stg += "\n\nestExp: " + this.estExp + "  -  Tipo: " + (typeof this.estExp);
	prop_stg += "\n\nargDecSep: " + this.argDecSep + "  -  Tipo: " + (typeof this.argDecSep);
	prop_stg += "\n\nargHasDec: " + this.argHasDec() + "  -  Tipo: " + (typeof this.argHasDec());
	prop_stg += "\n\ngetSigDig: " + this.getSigDig() + "  -  Tipo: " + (typeof this.getSigDig());
	prop_stg += "\n\ngetSignificand: " + this.getSignificand() + "  -  Tipo: " + (typeof this.getSignificand());
	prop_stg += "\n\ngetMagOrder: " + this.getMagOrder() + "  -  Tipo: " + (typeof this.getMagOrder());
			
	return prop_stg;
}

// @retun: quantidade de dígitos significativos (Number)
FormatWbc.prototype.getSigDig = function(){
	if (isNaN(this.valorNum)) {
		return NaN;
	}
	var signif_stg = this.getSignificand();
	signif_stg = signif_stg.replace(/[\.,]/, "");	
	return signif_stg.length;
}

/* @retun: significando (ou mantissa) do número (String)
* @param arred- define se o significando será arredondado de acordo com "this.cdec" e "this.prec" (Boolean)
*/
FormatWbc.prototype.getSignificand = function(arred){
	var signif = "";
	if (this.valorNum==0) {
		return "0";
	}
	if (isNaN(this.valorNum)) {
		return "";
	}
	var comp_arg = (""+this.valorArg).length;		
	if (comp_arg<17) {
		//Código Criado por Alfredo Borba (http://webcalc.com.br)		
		var val_ref = this.valorNum;				
		if (arred && !isNaN(this.cdec)) {
			val_ref = this.getValueRound(this.cdec, this.prec);
		}		
		var expo_stg = (val_ref).toExponential();
		signif = expo_stg.slice(0, expo_stg.indexOf("e"));
		signif += this.getArgLastZeros(true);
		if (this.decSep==".") {
			signif = signif.replace(/,/, ".");
		}
		else {
			signif = signif.replace(/\./, ",");
		}
		if (parseFloat(signif)>9 && signif.indexOf(".")==-1 && signif.indexOf(",")==-1) {
			signif = signif.slice(0, 1) + this.decSep + signif.slice(1);
		}
		return signif;
	}
	else {
		//Adaptação do Código Criado por Stephen Ostermiller (Copyright (C) 2001 Stephen Ostermiller  -  http://ostermiller.org/contact.pl?regarding?JavaScript+Significant+Figures)
		//var s = (""+this.valorArg).replace(/,/, ".");
		var s = "" + this.valorNum;				
		if (arred && !isNaN(this.cdec)) {
			var val_ref2 = parseFloat(s);			
			s = "" + this.getValueRound(this.cdec, this.prec, val_ref2);
		}
		
		var beginning = true;
	    var seenDot = false;
	    var seenSomething = false;
	    var zeros = "";
	    var leadZeros = "";
	    var all = "";
	    var decPlaces = 0;
	    var totalDecs = 0;
	    var pos = true;
		for (var i=0; i<s.length; i++){
	        var c = s.charAt(i);
	        if (c>='1' && c<='9'){
	            all += zeros + c;
	            zeros = "";
	            seenSomething = true;
	            if (!seenDot){                
	                totalDecs++;
	                decPlaces++;
	            }
	            beginning = false;
	        } else if (c=='0'){
	            if (seenDot){
	                if (seenSomething){ 
	                    all += zeros + c;
	                    zeros = "";
	                } else {                                       
	                    leadZeros += c;
	                    decPlaces--;
					}
	            } else {
	                totalDecs++;
	                if (seenSomething){
	                    leadZeros += c;
	                    decPlaces++;
	                    zeros += c;
	                } else {                                       
	                    leadZeros += c;
	                }
	            } 
	            beginning = false;
			} else if (!seenDot && c=='.'){
	            all += zeros;
	            zeros = "";
	            seenDot=true;
	            beginning = false;
			} else if (c=='e' || c=='E' && i+1<s.length){
	            var raised = parseInt(s.substring(i+1, s.length));
	            decPlaces += raised;
	            totalDecs += raised;
	            i = s.length;
	        } else if (beginning && (c=='+' || c=='-')){
	            if (c=='-'){
	                pos = !pos;
	            }
			}
	    }
		if (all == ""){
	        return leadZeros;
	    } else {
			if (all.length!=1) {
				signif = all.slice(0, 1) + this.decSep + all.slice(1);
			}
			else {signif = all;}
	        return signif;
	    }
	}
}

// @retun: parte exponencial da notação científica do número (String)
FormatWbc.prototype.getExp = function(){
	if (isNaN(this.valorNum)) {
		return "";
	}
	var expo_stg = (this.valorNum).toExponential();
	expo_stg = expo_stg.slice(expo_stg.indexOf("e")+1);
	return expo_stg;
}

// @retun: ordem de magnitude do número  =  Exp. da notação científica (String)
FormatWbc.prototype.getMagOrder = function(){	
	return this.getExp();
}

// @retun: erro absoluto de um número (Number)
FormatWbc.prototype.getAbsError = function(){
	//????Cria código
	return 0;
}

// @retun: erro relativo de um número (Number)
FormatWbc.prototype.getRelatError = function(){
	//????Cria código
	return 0;
}

// @retun: "true" se o número entrado tiver parte decimal (Boolean)
FormatWbc.prototype.argHasDec = function(){
	var arg_val = "" + this.valorArg;
	var arg_dec = false;	
	var dec_sep_cont = 0;
	var pt_cont = 0;
	var vg_cont = 0;
	if (arg_val.charAt(arg_val.length-1)=="." || arg_val.charAt(arg_val.length-1)==",") {
		return false;
	}		
	for (var j=arg_val.length-1; j>0; j--) {
		var char_teste = "";
		if (arg_val.charAt(j)==".") {
			pt_cont++;
		}
		else if (arg_val.charAt(j)==",") {
			vg_cont++;
		}
	}	
	if (pt_cont>0 && vg_cont>0) {
		dec_sep_cont = Math.min(pt_cont, vg_cont);
		this.argDecSep = (pt_cont<vg_cont)? "." : ",";
	}
	if ((pt_cont==1 && vg_cont==0) || (pt_cont==0 && vg_cont==1)) {
		dec_sep_cont = 1;
		this.argDecSep = (pt_cont==1)? "." : ",";
	}
	if (dec_sep_cont>0 && !this.argSemDec) {
		arg_dec = true;
	}
	return arg_dec;
}

/* @retun: últimos zeros da parte decimal do número entrado (String)
* @param sig: indica se o método está sendo usado pelo método "getSigDig()" (Boolean)
*/
FormatWbc.prototype.getArgLastZeros = function(sig){
	if (!this.argHasDec()) {return "";}
	var arg_sig = (sig)? sig : false;
	var arg_val = "" + this.valorArg;
	if (arg_val.indexOf("e")!=-1) {
		arg_val = arg_val.slice(0, arg_val.indexOf("e"));
	}
	var arg_zeros = "";
	for (var i=arg_val.length-1; i>0; i--) {
		if (arg_val.charAt(i)==0) {
			arg_zeros += "0";
		}
		else {
			if (!arg_sig) {
				if ((""+this.valorNum).indexOf(".")==-1 && this.argDecSep!="" && arg_zeros!="") {					
					arg_zeros = this.decSep + arg_zeros;
				}
				break;
			}			
			if (arg_val.charAt(i)==this.argDecSep && (this.valorNum.toExponential()).indexOf(".")==-1) {			
				arg_zeros = this.argDecSep + arg_zeros;
			}		
			if (arg_val.charAt(i)!="." && arg_val.charAt(i)!=",") {				
				break;
			}
		}
	}	
	return arg_zeros;
}



/* #################################################################
* Pendências:
* ??Resolver problema de resultados "distorcidos" de cálculos com números muito baixo (Ex: 1e-9* 1000=0.0000010000000000000001). Utilizar método "toPrecision" ("auto") para repetições (Ex: "...9999999" e "...0000000001" no final da parte decimal dos números calculados (ent=false), utilizando a quantidade de dígitos significativos sem a parte repetida)
* Revisar calculadora para trabalhar com números formatados nos resultados
* Revisar calculadora para trabalhar com números formatados na expressão de entrada (criar objeto para análise e formatação de expressões matemáticas)
* Realizar testes abrangentes e rigorosos!!
* Criar janela de configurações de formatação no menu
* Concluir métodos:
* - getAbsError()
* - getRelatError()
* Criar métodos de classe para operações com números formatados (??)
* Incorporar nas calculadoras a opção de considerar os algarismos significativos no resultado, ao invés de quantidade fixa de casas decimais (área de configuração de cada calculadora)
*
* Bugs:
* ???Ex: valorArg = 1.0000000000000001000 -> valorFormat = 1,000 ?? -> Número com mais de 15 zeros decimais retorna apenas o valor inteiro (Limitação do Javascript -> apresenta número com máx. de 16 casas decimais -> testado no IE e Firefox) e o método getArgLastZeros() acrescenta os últimos zeros (Ex: ",000") ao valor formatado (Verificar forma de contornar o "problema" ??)
* ????arrendodamento com notação 1 e 2 pode perder algarismos significativos
* #################################################################
*/